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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With