8

假设我有一个 F# 计算要在 C# 中处理,我想让它们同步运行。引擎盖下面有什么区别:

    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;
    }

抱歉,如果这似乎是一个简单的问题,我对异步编程很陌生!

4

1 回答 1

11

I think they will be essentially the same - as Reed says, the first one queues the work directly while the other one creates a Task, but the created Task is fairly lightweight object (under the cover, this is almost the same and the task is created using TaskCompletionSource - you can see the code here).

If you are in control of the F# library, then my recommendation would be to only expose a method that returns Task and hide the F# async - this will make the usage from C# much more convenient and you will avoid all the special F# types (like options). If you have someWork function in F#, then I would write:

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

On the C# side, you will see a nice overloaded method that returns Task and works well with await. Of course, you can just await the result synchronously using Result, but the overhead is not too big - and the fact that you're exposing nice C# API will make it easier to integrate F# in your system.

于 2013-09-03T16:57:54.357 回答