public async Task<string> GetName(int id)
{
Task<string> nameTask =
Task.Factory.StartNew(() => { return string.Format("Name matching id {0} = Developer", id); });
return nameTask.Result;
}
上記のメソッドreturnステートメントでは、Task.Resultプロパティを使用しています。
public async Task<string> GetName(int id)
{
Task<string> nameTask =
Task.Factory.StartNew(() => { return string.Format("Name matching id {0} = Developer", id); });
return await nameTask;
}
ここでは、待機タスクを使用しています。 awaitが呼び出しスレッドを解放すると思っても、Task.Resultがそれをブロックすると思っても間違いはありませんか?
Awaitが呼び出しスレッドを解放すると思っても、Task.Resultがそれをブロックすると思っても間違いはありませんか?
通常、はい。 await task;
は現在のスレッドを「譲ります」。 task.Result
は現在のスレッドをブロックします。 await
は非同期待機です。 Result
はブロッキング待機です。
さらに小さな違いがもう1つあります。タスクが障害状態(つまり、例外あり)で完了した場合、await
はその例外をそのまま(再)発生させますが、Result
はラップしますAggregateException
の例外。
補足として、Task.Factory.StartNew
。ほとんどの場合、正しい方法ではありません。バックグラウンドスレッドで作業を実行する必要がある場合は、Task.Run
。
動的タスクの並列処理 ;を実行している場合、Result
とStartNew
の両方が適切です。それ以外の場合は、回避する必要があります。 非同期プログラミング を実行している場合、どちらも適切ではありません。
Awaitが呼び出しスレッドを解放すると思っても、Task.Resultがそれをブロックすると思っても間違いはありませんか?
タスクが同期的に完了していない限り、あなたは正しいです。その場合、await
は最初にタスクが完了したかどうかをチェックするため、_Task.Result
_または_await task
_のいずれかを使用すると、同期的に実行されます。それ以外の場合、タスクが完了していない場合、await
を使用すると_Task.Result
_の呼び出しスレッドがブロックされますa同期してタスクの完了を待ちます。異なるもう1つの点は、例外処理です。前者はAggregationException
(1つ以上の例外を含む可能性があります)を伝播しますが、後者はそれをアンラップして、基になる例外を返します。
補足として、 syncメソッドで非同期ラッパーを使用することは悪い習慣であり、回避する必要があります。 また、非同期メソッド内で_Task.Result
_を使用すると、デッドロックが発生し、また避けてください。