このページをはてなブックマークに追加このページを含むはてなブックマーク このページをlivedoor クリップに追加このページを含むlivedoor クリップ
*目次 [#xdce85f8]

#contents


*バックグラウンドワーカーの基本動作 [#yeb8e09a]

1:メインスレッドからバックグラウンドワーカーのRunWorkerAsyncメソッドを呼ぶ。

2:バックグラウンドワーカーでDoWorkイベントが発生する。このイベント内で時間のかかる処理などを実行する。

3:DoWorkイベントメソッドの実行が終わると、バックグラウンドワーカーでRunWorkerCompletedイベントが発生する。このイベントはメインスレッドで実行される。

|メインスレッド|バックグラウンドスレッド|h
||DoWorkイベント発生|
|RunWorkerCompletedイベント発生||

*バックグラウンドスレッドに情報を渡す [#ea3c96c3]

 バックグラウンドスレッドを開始するために、メインスレッドはバックグラウンドワーカーのRunWorkerAsyncメソッドを実行する。その際、引数にObject型のパラメータを指定できる。ここにバックグラウンドスレッドに渡したい情報を指定する。
 すると、バックグラウンドスレッド側はDoWorkイベントメソッドの仮引数であるDoWorkEventArgs型のeのArgumentプロパティを参照することで情報を取り出すことができる。

*バックグラウンド処理の終了 [#a00c8b14]

 バックグラウンドメソッドのDoWorkイベントメソッドが終了すると、メインスレッドでRunWorkerCompletedイベントが発生する。

 RunWorkerCompletedのイベントメソッドは次の2つの仮引数を持つ。

+イベントの発生したオブジェクトを示すsender
+RunWorkerCompletedEventArgs型のe
--e.Errorプロパティに例外オブジェクトが設定されていれば、DoWorkイベントメソッドで例外が発生したと判断できる。
--DoWorkイベントメソッド開始時にメインスレッドからバックグラウンドスレッドにパラメータを渡したように、DoWorkイベントメソッドからメインスレッドにパラメータを渡すことが可能である。
---e.Rusultプロパティでやり取りされる。

**バックグラウンド処理が終了するタイミング [#pd765e7f]

+DoWorkイベントメソッドが正常に終了した。
+DoWorkイベントメソッドで例外が発生して、スローされてきた。
+DoWorkイベントメソッド内でバックグラウンドのキャンセルが実行された。

*バックグラウンド処理の注意 [#rfdad151]

-DoWorkイベントメソッド内では、コントロールなどのインタフェースにアクセスしてはいけない。
--なぜならば、Windowsのフォームに関するコンポーネントは[[スレッドセーフ]]((複数のスレッドから同時にアクセスしても問題がないという意味。))ではないからである。
--バックグラウンドワーカーのWorkerReportsProgressプロパティをTrueに設定すれば、DoWorkイベントメソッド内でReportProgressメソッドを実行して、メインスレッドでProgressChangedイベントを発生させることができる。その際、バックグラウンド処理の進捗や状態を渡すこともできる。
---つまり、バックグラウンド処理中にコントロールにアクセスしたい場合は、バックグラウンドスレッドから一旦メインスレッドに戻ってからコントロールにアクセスし、またバックグランドスレッドに戻ってくるという手続きになる。
-1つのバックグラウンドワーカーで同時に行えるバックグラウンド処理は1つだけである。
--つまり、バックグラウンドスレッドの実行中に、再度RunWorkerAsyncメソッドを実行してはいけない。
--すでにバックグラウンドワーカーが実行中かどうかはIsBusyプロパティを参照すれば確認できる。

*バックグラウンド処理の停止 [#kf2a9834]

**メインスレッドからバックグラウンドスレッドの処理を停止する [#i8d5f942]

 メインスレッドでBackgroundWorker.CancelAsyncメソッドを実行する。すると、バックグラウンドワーカーのCancellationPendingプロパティがTrueに変化する。バックグラウンドスレッドでは、CancellationPendingプロパティを定期的に監視しており、このプロパティがTrueになると、停止処理に移行する。

 バックグラウンドワーカーは停止処理として、イベントメソッドのパラメータeのCancelプロパティをTrueに設定して、処理を中断する。

 その後、メインスレッドのRunWorkerCompletedイベントが発生する。つまり、RunWorkerCompletedイベントメソッドのe.Cancelledプロパティを参照することで、バックグラウンドスレッドが正常に終了したのか、こちからの停止命令で中断したのかを判定できる。

*参考文献 [#y6a33996]

-『VisualBasic2008入門』