「C Sharpの基礎 - マルチスレッド」の版間の差分

ナビゲーションに移動 検索に移動
197行目: 197行目:


== ConfigureAwait(false) ==
== ConfigureAwait(false) ==
GUIアプリケーションでは、以下のように記述すると、簡単にデッドロックが発生する。<br>
GUIアプリケーションにおいて、<code>Wait</code>メソッドおよび<code>Result</code>メソッドを使用する場合、デッドロックが発生する。<br>
なぜなら、TaskのWaitメソッドやResultは、元のスレッドへ戻ろうとするからである。<br>
これは、<code>Task</code>クラスの<code>Wait</code>メソッドや<code>Result</code>メソッドは、元のスレッドへ戻るからである。<br>
<br>
<br>
以下の場合、methodAsync().Wait()を呼んだ時点で親スレッドがスリープする。<br>
以下の例では、まず、methodAsync().Wait()を実行した時点で親スレッドがスリープする。<br>
なぜなら、methodAsync()の終了後に親スレッドに戻ろうとするが、既に親スレッドがスリープしているため、<br>
次に、methodAsyncメソッドの完了後、親スレッドに戻る時、既に親スレッドがスリープしているため、処理を続けることができない。<br>
処理を続けることができないからである。<br>
そのため、親スレッドは子スレッドを待ち続け、子スレッドは親スレッドに戻ろうとして、デッドロックが発生する。<br>
その結果、親スレッドは子スレッドを待ち続け、子スレッドは親スレッドに戻ろうとして、デッドロックが発生する。<br>
  <syntaxhighlight lang="c#">
  <syntaxhighlight lang="c#">
  // デッドロックが起きるサンプルコード(GUIアプリケーションのみ)
  // デッドロックが起きるサンプルコード(GUIアプリケーションのみ)
218行目: 217行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
対策として、以下のように記述するとデッドロックが回避できる。(戻るスレッドはどこでもよい場合)<br>
対策として、<code>ConfigureAwait(false)</code>を使用するとデッドロックが回避できる。<br>
<br>
<code>ConfigureAwait(false)</code>は、メソッドの終了後に親スレッド(呼び出し元)に戻らなくてもよいことを指定する。<br>
ブロックされたスレッドに戻らなくなるため、methodAsyncメソッドが終了した時にcallMethodメソッドに戻ることができる。<br>
  <syntaxhighlight lang="c#">
  <syntaxhighlight lang="c#">
  // デッドロックが起きないサンプルコード(GUIアプリケーションのみ)
  // デッドロックが起きないサンプルコード(GUIアプリケーションのみ)

案内メニュー