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

我创建了一个返回此数据类型的F#库

FSharpAsync<IEnumerable<Tupel>> 

如何访问FSharpAsync类型以便我可以通过C#中的元组进行枚举并打印出内容?

通常不建议在将由C#客户端使用的公共接口中公开F#类型(如FSharpAsync (请参阅F#组件设计准则 )。 您可以使用Async.StartAsTask (在F#端)将操作公开为可以从C#轻松使用的Task

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

 // Assuming you have an operation like this let asyncDoWork () : Async> = (...) // 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添加到名称的末尾 (它与F#不重叠,后者将Async添加到前面):

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

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

参考FSharp.Core.dll,然后:

 FSharpAsync>> async = ... IEnumerable> result = FSharpAsync.RunSynchronously(async, timeout: FSharpOption.None, cancellationToken: FSharpOption.None); 

FSharpAsync位于Microsoft.FSharp.Control命名空间中。

FSharpOption位于Microsoft.FSharp.Core命名空间中。

您可以通过FSharpAsync的静态方法对其进行操作 。 您获得的async可能是Async<'T>类型,它没有实例方法。

如果你看一下返回类型FSharpAsync>>这告诉我们这是一个异步操作,当由FSharpAsync中的静态方法执行时将返回一个IEnumerable>因此,这就成了F#库创建一个C#代码可以执行的操作(异步操作)的情况,因此它可以作为延迟操作,以后可以在从F#库获取它之后执行,当你执行这个惰性操作时返回一个IEnumerable,它在某种意义上是懒惰的,你从它中提取值并在生成值的同时。

我想你可以从你的F#库返回IEnumerable> ,根本不需要返回Async操作。 但这又取决于你的F#库做了什么,以及它应该如何生成这个IEnumerable