c# - Async.RunSynchronously() 与 Async.StartAsTask().Result

标签 c# asynchronous f# c#-to-f#

假设我有一个 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;
    }

抱歉,如果这看起来像是一个简单的问题,我对异步编程还很陌生!

最佳答案

我认为它们本质上是相同的——正如 Reed 所说,第一个直接将工作排队,而另一个创建一个 Task,但是创建的 Task 是相当轻量级的对象(在幕后,这几乎是一样的,任务是使用 TaskCompletionSource 创建的 - 你可以 see the code here )。

如果您控制了 F# 库,那么我的建议是只公开一个返回 Task 的方法并隐藏 F# async - 这将使 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# 更容易集成到您的系统中。

关于c# - Async.RunSynchronously() 与 Async.StartAsTask().Result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18597436/

相关文章:

c# - 在 WinForms 应用程序中利用预先编写的 View 代码

java - 异步日志

f# - fscheck 生成大小在 min 和 max 之间的字符串

c# - 在 Windows 服务中启动调试器

c# - 在内存数据库提供程序中使用EF core进行asp.net core应用程序单元测试的优点

c# - 添加或减去的值会导致无法表示的 DateTime。参数名称

javascript - 试图让异步代码在for循环内同步运行

Javascript - Promise 执行器内有多个 .then 子句

f# - 为什么 "->"在 F# 理解中被弃用?

list - 获取 F# 中两个整数列表之间的匹配数