我是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#进行访问?
答案 0 :(得分:2)
这篇文章准确显示了您的要求:
但是,您最终使用C#的monad语法。由于LINQ是为查询而设计的,因此看起来有点奇怪。此外,不支持try / catch或使用dispose。
如果没有正确的monad语法,你从Async.BuildPrimitive获得的“ReadAllAsync”将没有相同的魔力。调用它很简单,但真正的实用程序能够组成它。
不幸的是,你最好只使用C#风格
答案 1 :(得分: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。