4

我是一名 C# 程序员,但我对 F# 中的异步工作流有疑问。假设我在 C# 类库中有以下类:

class File {
 IAsyncResult BeginReadAll(string fileName, AsyncCallback callback, object state){}
 string EndReadAll(IAsyncResult result){}
}

我的理解是,我可以在 F# 中创建一个名为 ReadAllAsync 的函数,我可以像这样调用它:

async {  let! rsp = ReadAllAsync() }

并且它不会阻塞调用线程,而是将其释放到线程池中,然后在操作完成时返回另一个线程。我想我了解如何使用 Async.Primitive 在 F# 中对此进行编码,但我的问题是:我可以从 C# 代码中调用这个 ReadAllAsync 函数吗?如果是这样,我如何将 F# 代码打包到类库中以从 C# 访问?

4

2 回答 2

2

这是一篇文章,准确地显示了您的要求:

http://codebetter.com/blogs/matthew.podwysocki/archive/2008/10/15/functional-c-implementing-async-computations-in-c.aspx

但是,您最终会使用 C# 的 monad 语法。由于 LINQ 是为查询而设计的,所以它看起来有点奇怪。此外,不支持 try/catch 或 using for dispose。

如果没有正确的 monad 语法,您从 Async.BuildPrimitive 获得的“ReadAllAsync”不会有同样的魔力。调用它很简单,但真正的实用程序是能够组合它。

不幸的是,您最好只使用 C# 样式,

于 2009-01-30T08:17:58.203 回答
2

令人高兴的是,当 Beta2 到来时,F# 核心库将在 Async 模块中有这个方法:

/// Return three functions that can be used to implement the .NET Asynchronous 
/// Programming Model (APM) for a given asynchronous computation.
/// 
/// The functions should normally be published as members with prefix 'Begin',
/// 'End' and 'Cancel', and can be used within a type definition as follows:
/// <c>
///   let beginAction,endAction,cancelAction = Async.AsBeginEnd computation
///   member x.BeginSomeOperation(callback,state) = beginAction(callback,state)
///   member x.EndSomeOperation(iar) = endAction(iar)
///   member x.CancelSomeOperation(iar) = cancelAction(iar)
/// </c>
///
/// The resulting API will be familiar to programmers in other .NET languages and 
/// is a useful way to publish asynchronous computations in .NET components.
static member AsBeginEnd : computation:Async<'T> ->                     // '
                             // The 'Begin' member
                             (System.AsyncCallback * obj -> System.IAsyncResult) * 
                             // The 'End' member
                             (System.IAsyncResult -> 'T) *              // '
                             // The 'Cancel' member
                             (System.IAsyncResult -> unit)

这将使使用 F# 编写异步代码变得容易,然后使用普通 APM 将其发布回 C# 或 VB。

于 2009-07-23T07:55:28.910 回答