2

タスク ベースの非同期開発に重点を置いているため、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;
}

しかし、これは間違っているように感じます。より優れた、よりエレガントなアプローチはありますか?

4

1 に答える 1

1

TaskWindows Phone 8 にベースの参照作成機能がないことに驚いています。

つまり、TaskCompletionSource さまざまな非同期パターン (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;
}
于 2012-11-27T02:28:20.563 に答える