2011-02-25 71 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)