6

一部の async/await コードをチェーン タスクに変換しているので、リリースされたフレームワークで使用できます。待機コードは次のようになります

public async Task<TraumMessage> Get() {
  var message = await Invoke("GET");
  var memorized = await message.Memorize();
  return memorized;
}

どこ

Task<TraumMessage> Invoke(string verb) {}
Task<TraumMessage> Memorize() {}

によって生成されたタスクをチェーンInvokeして返すことを望んでいましたが、結果は. 私が最終的に解決した解決策は、私のシグナルとしてです:MemorizeMemorizeTask<Task<TraumMessage>TaskCompletionSource<TraumMessage>

public Task<TraumMessage> Get() {
  var completion = new TaskCompletionSource<TraumMessage>();
  Invoke("GET").ContinueWith( t1 => {
     if(t1.IsFaulted) {
       completion.SetException(t1.Exception);
       return;
     }
     t1.Result.Memorize().ContinueWith( t2 => {
       if(t2.IsFaulted) {
         completion.SetException(t2.Exception);
         return;
       }
       completion.SetResult(t2.Result);
     });
  });
  return completion.Task;
}

なしでこれを達成する方法はありTaskCompletionSourceますか?

4

3 に答える 3

4

Yes, the framework comes with a handy Unwrap() extension method for exactly what you want.

Invoke("GET").ContinueWith( t => t.Result.Memorize() ).Unwrap();

If you're doing cancellation then you'll need to pass cancel tokens into the appropriate places, obviously.

于 2012-04-25T13:20:05.200 に答える
1

それがあなたが望むことを達成する唯一の方法だと思います。異種のタスクを一緒にチェーンすることは、継続 API ではサポートされていないためTaskCompletionSource、作業を調整する必要があるようなものを使用する必要があります。

私はこのマシンに Async CTP をインストールしていませんが、コードを逆コンパイラ (または IL の読み方を知っている場合は ILDASM) で調べて、何が行われているかを確認してください。カバーの下で TCS コードと非常によく似たことが行われているに違いありません。

于 2011-07-30T17:10:45.770 に答える
0

添付された子タスクを使用できます。すべての子タスクが完了した場合にのみ、親タスクは完了ステータスに遷移します。例外は親タスクに伝播されます。親タスクのデリゲートが終了した後に結果が割り当てられるため、結果ホルダーが必要になりますが、親タスクの継続が実行されるときに設定されます。

このような:

public class Holder<T> where T: class
{
   public T Value { get; set; }
}

public Task<Holder<TraumMessage>> Get() {
  var invokeTask = Invoke("GET");
  var result = invokeTask.ContinueWith<Holder<TraumMessage>>(t1 => {
    var holder = new Holder<TraumMessage>();
    var memorizeTask = t1.Result.Memorize();
    memorizeTask.ContinueWith(t2 => {
      holder.Value = t2.Result;
    }, TaskContinuationOptions.AttachedToParent);
    return holder;
  });
  return result;
}
于 2011-09-04T04:09:25.240 に答える