문제

Lets say I had an F# computation to deal with in C# and I wanted to make them run synchronously. What would be the difference underneath the hood between:

    public static T RunSync<T>(FSharpAsync<T> computation)
    {
        return FSharpAsync.RunSynchronously(computation,
            timeout: FSharpOption<int>.None,
            cancellationToken: FSharpOption<System.Threading.CancellationToken>.None
            );
    }

or

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

Sorry if this seems like a simple question, I am quite new to async programming!

도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top