Async.RunSynchronously()与Async.StartAsTask().Result的区别

9
假设我需要在C#中处理一个F#计算,并且希望它们同步运行。在底层,以下两种方式有何区别呢?
    public static T RunSync<T>(FSharpAsync<T> computation)
    {
        return FSharpAsync.RunSynchronously(computation,
            timeout: FSharpOption<int>.None,
            cancellationToken: FSharpOption<System.Threading.CancellationToken>.None
            );
    }

或者

    public static T RunSync<T>(FSharpAsync<T> computation)
    {
        return FSharpAsync.StartAsTask(computation,
            taskCreationOptions: FSharpOption<TaskCreationOptions>.None,
            cancellationToken: FSharpOption<System.Threading.CancellationToken>.None
            ).Result;
    }

如果这个问题看起来很简单,那我很抱歉,因为我对异步编程还很陌生!

1个回答

13

我认为它们基本相同-如Reed所说,第一个直接排队工作,而另一个创建了一个任务,但所创建的任务是相当轻量级的对象(在幕后,这几乎是相同的,使用TaskCompletionSource创建任务 - 您可以在此处查看代码)。

如果您控制F#库,则我的建议是仅公开返回任务的方法并隐藏F#异步-这将使来自C#的使用更加方便,并避免所有特殊的F#类型(例如选项)。如果您在F#中有someWork函数,则可以编写:

type NiceCSharp = 
  static member SomeWork() =
    Async.StartAsTask(someWork())
  static member SomeWork(cancellationToken) =
    Async.StartAsTask(someWork(), cancellationToken = cancellationToken)

在C#端,你会看到一个很好的重载方法,它返回Task并且与await非常兼容。当然,你也可以使用Result同步等待结果,但开销不会太大 - 并且暴露一个良好的C# API将使集成F#到你的系统中更容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接