实施'等待'键入行为到不可等待的任务

时间:2014-04-14 14:45:03

标签: c# wcf events asynchronous delegates

访问WCF服务时,Windows Phone 8和标准.NET的API存在差异。 WP8的API强制使用回调而不是提供等待的接口。此外,我使用自定义标头进行服务调用,其中还包括在这两个平台上不同的一些恶作剧(我希望我的代码可以在两者上运行)。

无论如何,我最终得到了类似的模式:

    private bool mOperationCompleted = false;
    private OperationResultType mOperationResult;

    public async Task<OperationResultType> WCFServiceRequestOperationName()
    {
        mClient.WCFServiceRequestOperationNameCompleted += WCFServiceRequestOperationNameCompleted;

        PerformRequest(mClient, () => mStoreClient.WCFServiceRequestOperationName(dem parameters for this particular call));

        while (!mOperationCompleted ) { await Task.Delay(500); /* delay isn't mandatory here */ }

        // Reset
        mOperationCompleted = false;

        // Return
        return mOperationResult;
    }

    void Client_WCFServiceRequestOperationNameCompleted(object sender, WCFServiceRequestOperationNameCompletedEventArgs e)
    {
        mOperationResult = e.Result;
        mOperationCompleted = true;
    }

这里的mClient是VS2012生成的ServiceReferenceClient。所以基本上当我等待异步操作时,我得到了等待的&#39;行为;即。

var result = await WCFServiceRequestOperationName();

所以我的问题是,如何在一个类中包装这个模式,所以我可以简单地以通用的方式调用它来进行任何WCF服务调用。我相当确定泛型和代理可能有一个解决方案,但我不能将事件作为参数传递,所以我不知道如何以通用的方式添加处理程序。

我想要这样的东西,因为我不想复制粘贴并为我的每个请求调整它。

1 个答案:

答案 0 :(得分:3)

您真的不想为WCF调用使用轮询模式。相反,请按照standard pattern for wrapping EAP members in TAP methods进行操作。我喜欢将它们作为扩展方法,因此它们只能编写一次,并且可以在任何地方使用:

public static Task<OperationResult> OperationTaskAsync(this WCFService client)
{
  var tcs = new TaskCompletionSource<OperationResult>();
  OperationCompletedEventHandler handler = null;
  handler = (_, e) =>
  {
    client.OperationCompleted -= handler;
    if (e.Error != null)
      tcs.TrySetException(e.Error);
    else if (e.Cancelled)
      tcs.TrySetCanceled();
    else
      tcs.TrySetResult(e.Result);
  };
  client.OperationCompleted += handler;
  client.OperationAsync();
  return tcs.Task;
}