12,796
回編集
103行目: | 103行目: | ||
== ConfigureAwait(false) == | == ConfigureAwait(false) == | ||
GUIアプリケーションでは、以下のように記述すると、簡単にデッドロックが発生する。<br> | |||
なぜなら、TaskのWaitメソッドやResultは、元のスレッドへ戻ろうとするからである。<br> | |||
<br> | |||
以下の場合、methodAsync().Wait()を呼んだ時点で親スレッドがスリープする。<br> | |||
なぜなら、methodAsync()の終了後に親スレッドに戻ろうとするが、既に親スレッドがスリープしているため、<br> | |||
処理を続けることができないからである。<br> | |||
その結果、親スレッドは子スレッドを待ち続け、子スレッドは親スレッドに戻ろうとして、デッドロックが発生する。<br> | |||
<source lang="c#"> | <source lang="c#"> | ||
// デッドロックが起きるサンプルコード(GUIアプリケーションのみ) | // デッドロックが起きるサンプルコード(GUIアプリケーションのみ) | ||
// コンソールアプリケーションでは正常に動作する | |||
public void callMethod() | public void callMethod() | ||
{ | { | ||
117行目: | 123行目: | ||
} | } | ||
</source> | </source> | ||
<br> | <br> | ||
対策として、以下のように記述するとデッドロックが回避できる。(戻るスレッドはどこでもよい場合)<br> | 対策として、以下のように記述するとデッドロックが回避できる。(戻るスレッドはどこでもよい場合)<br> | ||
<source lang="c#"> | <source lang="c#"> | ||
// デッドロックが起きないサンプルコード | // デッドロックが起きないサンプルコード(GUIアプリケーションのみ) | ||
public void callMethod() | public void callMethod() | ||
{ | { | ||
130行目: | 132行目: | ||
} | } | ||
public async Task | public async Task methodAsync() | ||
{ | { | ||
return await Task.Delay(1000).ConfigureAwait(false); | return await Task.Delay(1000).ConfigureAwait(false); |