5

非同期タスクが正常に完了したときにコードを実行したいと考えています。

Task.ContinueWithドキュメントや Web 上の例を読んで、 を使用して指定できると思いましたTaskContinuationOptions.OnlyOnRanToCompletion

ただし、これは期待どおりに動作しません。

次のコードは、Visual Studio 2012、.Net 4.5 で作成されたコンソール プログラムです。

using System;
using System.Threading.Tasks;

namespace TaskContinueTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var jobTask = Task.Factory.StartNew(() => { });

            jobTask.ContinueWith((task, options) =>
            {
                Console.WriteLine("Completed handler. Task status is {0}", task.Status);
            }, TaskContinuationOptions.OnlyOnRanToCompletion);

            jobTask.ContinueWith((task, options) =>
            {
                Console.WriteLine("Faulted handler. Task status is {0}", task.Status);
            }, TaskContinuationOptions.OnlyOnFaulted);

            Console.ReadLine();
        }
    }
}

実行すると、次の出力が得られます。

Completed handler. Task status is RanToCompletion
Faulted handler. Task status is RanToCompletion

これは非常に驚くべきことです(少なくとも私にとっては)。なぜ両方の継続が予定されているのですか?

で例外をスローすると同じ動作になりjobTaskますが、出力は次のようになります。

Completed handler. Task status is Faulted
Faulted handler. Task status is Faulted

フレームワークはタスクのステータスを明確に認識していますが、なぜ両方の継続がまだスケジュールされているのでしょうか?

4

1 に答える 1

8

問題は、あなたが誤ってこの過負荷と呼んでいることだと思います

public Task ContinueWith(
    Action<Task, Object> continuationAction,
    Object state
)

あなたが欲しいのはこの過負荷です:

public Task ContinueWith(
    Action<Task> continuationAction,
    TaskContinuationOptions continuationOptions
)

単一のパラメーターを使用するには、ラムダ式を変更する必要があります。

Task.ContinueWith(task => Console.WriteLine(...),
    TaskContinuationOptions.OnlyOnRanToCompletion);
于 2013-01-19T12:22:38.577 に答える