且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

从 C# 引用异步 F# 数据类型

更新时间:2023-01-30 15:11:34

通常不建议在 C# 客户端将使用的公共接口中公开 F# 类型,例如 FSharpAsync(请参阅F# 组件设计指南).您可以使用 Async.StartAsTask(在 F# 端)将操作公开为易于从 C# 使用的 Task.

It is generally not recommended to expose F# types such as FSharpAsync in a public interface that will be used by C# clients (see F# component design guidelines). You can use Async.StartAsTask (on the F# side) to expose the operation as a Task<T> that is easy to use from C#.

事实上,我也会用命名类型(捕获数据结构的含义)替换元组.元组可以在 C# 中使用,但它们在 C# 中不是惯用的:

In fact, I would also replace the tuple with a named type (that captures the meaning of the data structure). Tuples can be used in C#, but they are not idiomatic in C#:

// Assuming you have an operation like this 
let asyncDoWork () : Async<seq<DateTime * string>> = (...)

// Define a named type that explains what the date-string pair means
type Item(created:DateTime, name:string) =
  member x.Created = created
  member x.Name = name

// Create a simple wrapper that wraps values into 'Item' type
let asyncDoWorkItems () = 
  async { let! res = asyncDoWork()
          return seq { for (d, n) in res -> Item(d, n) } }

现在,要将操作公开给 C#,***实践是使用具有重载静态方法的类型.该方法将操作作为一项任务启动,一个重载指定取消标记.这些的 C# 命名约定是将 Async 添加到名称的 end(这与 F# 将 Async 添加到前面):

Now, to expose the operation to C#, the best practice is to use a type with an overloaded static method. The method starts the operation as a task and one overload specifies cancellation token. The C# naming convention for these is to add Async to the end of the name (which doesn't overlap with F# which adds Async to the front):

type Work = 
  static member DoWorkAsync() =
    Async.StartAsTask(asyncDoWorkItems())
  static member DoWorkAsync(cancellationToken) =
    Async.StartAsTask(asyncDoWorkItems(), cancellationToken = cancellationToken)

然后您的 C# 代码可以使用 Work.DoWorkAsync() 并以通常的 C# 样式处理任务.它甚至可以与将(可能)添加到 C# 5 中的 await 关键字一起使用.

Your C# code can then use Work.DoWorkAsync() and work with the task in the usual C# style. It will even work with the await keyword that will be (probably) added to C# 5.