如何在没有基于任务的代理的情况下处理Windows Phone 8中的服务引用

时间:2012-11-27 01:52:23

标签: c# async-await windows-phone-8 service-reference

由于非常重视基于任务的异步开发,我惊讶地发现Windows Phone 8中的服务引用不支持基于任务的实现。相反,他们使用“XYZCompleted”基于事件的异步方法。

因此,这样的代码是必要的:http://codepaste.net/fqyt47

public async Task<IEnumerable<MyService.Character>> GetCharactersAsync()
{
    var _Task = new TaskCompletionSource<IEnumerable<MyService.Character>>();
    var _Client = new MyService.ServiceClient();
    _Client.GetCharactersCompleted += (s, e) =>
    {
        var _Characters = e.Result as IEnumerable<MyService.Character>;
        if (e.Error != null && !_Task.TrySetException(e.Error))
            System.Diagnostics.Debugger.Break();
        else if (e.Cancelled && !_Task.TrySetCanceled())
            System.Diagnostics.Debugger.Break();
        else if (!_Task.TrySetResult(_Characters))
            System.Diagnostics.Debugger.Break();
    };
    _Client.GetCharactersAsync();

    return await _Task.Task;
}

然而,这感觉不对。是否有更好,更优雅的方法?

1 个答案:

答案 0 :(得分:1)

我很惊讶Windows Phone 8没有基于Task的参考创建。

那就是TaskCompletionSource is the standard way of interoperating with various asynchronous patterns (including EAP)

通常使用await可以使用的扩展方法来完成,但它们本身不是async

public Task<IEnumerable<MyService.Character>> GetCharactersTaskAsync(this ServiceClient client)
{
  var tcs = new TaskCompletionSource<IEnumerable<MyService.Character>>();
  client.GetCharactersCompleted += (s, e) =>
  {
    if (e.Error != null) tcs.SetException(e.Error);
    else if (e.Cancelled) tcs.SetCanceled();
    else tcs.SetResult(e.Result);
  };
  client.GetCharactersAsync();
  return tcs.Task;
}