2011-10-19 11 views
0

私はアプリケーションで本当に奇妙なバグを見つけようとしていますが、探しているうちにBackgroundWorkerがどのように動作するのか疑問に思っています。実行する前にBackgroundWorkerを破棄しましたか?

私はこのようなコードがある場合:

var bg = new BackgroundWorker(); 
bg.DoWork += MyHandler; 
bg.RunWorkerAsync 

を実行したことがないだろうとしたとにかくありますか?私が心に留めていることは、BGが実際に実行する前に、範囲外になり、BGによって主張されていることです。

それは起こりますか?

+0

Dispose()を明示的に呼び出す必要があります。ガベージコレクションもできません。あなたのMyHandler()メソッドは、* sender *引数を通じてBGWオブジェクトへの暗黙の参照を持ちます。例外をチェックするのを忘れるのはよくある間違いです。 –

答えて

2

次の行に例外が発生した場合、おそらくDoWorkは呼び出されません。しかし、私はこれがあなたの問題だとは思わない。それ以外の場合、RunWorkerAsnycは実行を何らかの方法でトリガーします.GraceWorkerへの参照がなくてもGCはインスタンスをガベージしません。
AsyncCompletedEventArgs.Errorプロパティをチェックして、DoWork-eventhandlerで例外が発生したかどうかを確認します。

1

いいえ、RunWorkerAsyncを呼び出したという事実は、別のスレッドで実行する作業を「キューに入れる」ので、あなたの作業者とは別の作業者への参照があります。何かが労働者を参照している場合、労働者は処分されません。より正確に言うと、ワーカーを実行しているスレッドインスタンスは、ワーカーの状態にアクセスするためにハンドルを持つ必要があります(ワーカーがスコープを離れるとワーカーが処分されるのを防ぎます)。

ワーカーが実行する前に処分する唯一の方法は、明示的に自分自身を処分すること(それが何であるかは考えられません)またはワーカーが実行する前にアプリケーションを終了することです。

+0

追加するだけです。これは、RunWorkerAsyncが例外を伴って失敗するか、新しいスレッドを開始するため、bg変数は依然として有効範囲内にあるため、関係なく処理することはできません。オブジェクトへの参照がまだ存在しているため、作成されたブロック内のどのような方法でもGCによって処理することはできません。 –

1

いいえ、RunWorkerAsyncは新しいスレッドを開始する必要があるためです。