2011-02-25 68 views
2

我在C#中用標準的「添加服務引用」對話框創建了一個庫,但其中實現的方法返回void,因此我無法在異步工作流中綁定它們。我不能使用Begin * End *接口,因爲每個方法都有不同的參數數量,所以它說「錯誤的參數數量」(類似的)。那麼,如何異步使用WCF服務(異步,因爲它旨在用於silverlight,其中一切都是異步的)?F#和WCF消費

+0

「return void所以我不能在異步工作流中綁定它們」 - 你是什麼意思? – Brian 2011-02-25 22:40:33

+1

我的意思是我怎麼才能用let來得到結果! – Viktor 2011-02-25 22:46:24

+0

什麼結果?他們返回無效? – Brian 2011-02-26 00:46:55

回答

3

我不清楚絆腳石是什麼,但是這個過程應該是

  • 有SvcUtil工具生成異步接口(帶開始/結束的方法)
  • 使用這些方法與FromBeginEnd轉換爲異步:http://msdn.microsoft.com/en-us/library/ee340508.aspx
  • 注意,如果該方法返回voidunit),那麼你將使用do!而不是let!異步內部工作流程
+0

如果Begin *函數需要一些參數,我該如何使用FromBeginEnd? – Viktor 2011-02-25 22:57:53

+0

你將不得不發佈一些不起作用的代碼,我不理解你。 – Brian 2011-02-26 00:47:27

+0

對不起,這是深夜,我有一個可怕的牙痛,我沒有仔細閱讀你提供的鏈接,錯過了我可以通過參數作爲第一參數。 – Viktor 2011-02-26 10:11:38

2

回答你的問題的一部分:「如果Begin函數需要一些參數,我該如何使用FromBeginEnd?」

你可以通過封閉的魔法來做到這一點。這裏有一些例子。如您所見,擴展方法採用參數,但傳遞給Async.FromBeginEnd的匿名函數與FromBeginEnd預期的簽名匹配。額外的參數在閉包中被捕獲並傳遞到匿名函數中的真實BeginXyz

您還可以使用的FromBeginEnd,首先需要額外的參數,然後將指針開始/結束的功能。最後,我在下面的AsyncGetReadStream方法做了過載 - 但是當有是BeginXyz多個重載我麻煩得到這個工作,所以我使用了大多數閉包。

open System 
open System.Data.Services.Client 

type System.Data.Services.Client.DataServiceContext with 

    member this.AsyncExecute<'a> (uri:Uri) = 
     Async.FromBeginEnd((fun (cb, state) -> this.BeginExecute<'a>(uri, cb, state)), 
          (fun iar -> this.EndExecute<'a>(iar) :?> QueryOperationResponse<'a>)) 

    member this.AsyncExecute<'a> (continuation:DataServiceQueryContinuation<'a>) = 
     Async.FromBeginEnd((fun (cb, state) -> this.BeginExecute<'a>(continuation, cb, state)), 
          (fun iar -> this.EndExecute<'a>(iar) :?> QueryOperationResponse<'a>)) 

    member this.AsyncExecuteBatch ([<ParamArray>] queries : DataServiceRequest[]) = 
     Async.FromBeginEnd((fun (cb, state) -> this.BeginExecuteBatch(cb, state, queries)), this.EndExecuteBatch) 

    member this.AsyncLoadProperty (entity:obj, propertyName:string) = 
     Async.FromBeginEnd((fun (cb, state) -> this.BeginLoadProperty(entity, propertyName, cb, state)), 
          this.EndLoadProperty) 

    member this.AsyncLoadProperty (entity:obj, propertyName:string, continuation:DataServiceQueryContinuation) = 
     Async.FromBeginEnd((fun (cb, state) -> this.BeginLoadProperty(entity, propertyName, continuation, cb, state)), 
          this.EndLoadProperty) 

    member this.AsyncLoadProperty (entity:obj, propertyName:string, nextLinkUri:Uri) = 
     Async.FromBeginEnd((fun (cb, state) -> this.BeginLoadProperty(entity, propertyName, nextLinkUri, cb, state)), 
          this.EndLoadProperty) 

    member this.AsyncSaveChanges() = 
     Async.FromBeginEnd(this.BeginSaveChanges, this.EndSaveChanges) 

    member this.AsyncSaveChanges (options:SaveChangesOptions) = 
     Async.FromBeginEnd((fun (cb, state) -> this.BeginSaveChanges(options, cb, state)), 
          this.EndSaveChanges) 

    member this.AsyncGetReadStream (entity:obj, args:DataServiceRequestArgs) = 
     Async.FromBeginEnd(entity, args, this.BeginGetReadStream, this.EndGetReadStream) 


type System.Data.Services.Client.DataServiceQuery with 

    member this.AsyncExecute() = 
     Async.FromBeginEnd(this.BeginExecute, this.EndExecute)