2011-09-15 3 views
14

TaskCompletionSource.SetResult(...)がすでに呼び出されている場合はTaskCompletionSource.TaskContinueWith(...)メソッドを使用するのは安全ですか?TaskCompletionSource.Task(これは.SetResultが呼び出されています)でContinueWithメソッドを呼び出すことは安全ですか?

この基本的なコードでは、うまくいけば、質問をフレームに役立ちます。task.ContinueWithが設定される前WebClient.DownloadStringCompletedイベントはすでに解雇している場合

// this was written inside the question box, please excuse any silly errors and lack of error checking (I'm not near VS right now)... 

private WebClient _webClient = new WebClient(); 

public Task<string> GetExamplePage() { 

    var tcs = new TaskCompletionSource<string>(); 

    web.DownloadStringCompleted += (s, ea) => tcs.SetResult(ea.Result); 

    web.DownloadStringAsync(new URI(@"http://www.example.com/example.html")); 

    return tcs.task; 
} 

public void ProcessExamplePage() { 

    var task = GetExamplePage(); 

    Thread.Sleep(1000); 

    task.ContinueWith(t => Console.WriteLine(t.Result)); // *line in question* 
} 

Console.WriteLine(...)が実行されますか?

MSDNが言うには、この(Task.ContinueWith)があります。

Task.ContinueWith方法

現在のタスクは、それが原因ランニングに完了したかどうか、完了するまで返されたタスクの実行のためにスケジュールされることはありませんが〜 完了に成功しました。処理されなかった例外のためにフォールトが発生しました。またはキャンセルされたために早めに が終了しました。

残念ながら、このメソッドが呼び出され、タスクが既に完了していればどうなるかは言及していません。

ご提供いただける情報がありがとうございます。 :)

答えて

17

はいこれは問題ありません。ContinueWithは前のタスクが完了したかどうかをチェックし、そうであれば直ちに継続をキューに入れます。

+2

これは新しい非同期操作を開始するか、これを同期して続行しますか? '' TaskCompletionSource''は非同期操作を開始しませんでした。 – annemartijn

+0

ニース。これに関する文書への参照は素晴らしいでしょう。 –

+0

@annemartijn元のタスク(または継続)が 'TaskCreationOptions.RunContinuationsAsynchronously'(または' TaskContinuationOptions。Run Continuations Asynchronously')を指定しているかどうかによって異なります - これらは*継続にのみ適用されます* - 継続が「TaskContinuationOptions。ExecuteSynchronously」を指定するかどうか(これは継続自体に適用されます)。 –

関連する問題