2009-01-30 86 views
4

我是C#程序員,但我對F#中的異步工作流程有疑問。假如我有一個C#類庫以下類:F#中的異步工作流程

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#訪問?

回答

2

這裏有一篇文章,說明你問什麼了:

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

但是,你最終使用C#的語法單子。由於LINQ被設計用於查詢,它看起來有點奇怪。此外,不支持try/catch或用於處置。

如果沒有正確的monad語法,從Async.BuildPrimitive獲得的「ReadAllAsync」不會具有相同的魔法。調用它很簡單,但真正的實用程序正在構建它。

你可能會更好過只使用C#的風格,遺憾的是,

2

令人高興的是,當Beta2的到來時,F#核心庫將有異步模塊中的這個方法:

/// 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。