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

时间:2011-07-25 01:43:34

标签: c# asynchronous f#

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

FSharpAsync<IEnumerable<Tupel<DateTime,string>>>

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

4 个答案:

答案 0 :(得分:14)

通常不建议在将由C#客户端使用的公共接口中公开FSharpAsync等F#类型(请参阅F# component design guidelines)。您可以使用Async.StartAsTask(在F#端)将操作公开为可以从C#轻松使用的Task<T>

实际上,我还会用命名类型(捕获数据结构的含义)替换元组。元组可以在C#中使用,但它们在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添加到前面):

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

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

答案 1 :(得分:4)

参考FSharp.Core.dll,然后:

FSharpAsync<IEnumerable<Tupel<DateTime,string>>> async = ...
IEnumerable<Tuple<DateTime, string>> result = FSharpAsync.RunSynchronously(async, timeout: FSharpOption<int>.None, cancellationToken: FSharpOption<CancellationToken>.None);

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

我认为您可以从F#库返回IEnumerable<Tupel<DateTime,string>>,并且根本不需要返回异步操作。但这又取决于你的F#库做了什么以及它应该如何生成这个IEnumerable