2017-12-11 11 views
-1
bg = new BackgroundWorker(); 
bg.DoWork += new DoWorkEventHandler(bg_DoWork); 
bg.RunWorkerAsync(); 

void bg_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while (true) 
    { 
     label1.Text = DateTime.Now.Minute.ToString() + " " + DateTime.Now.Second.ToString(); 
    } 
} 

bg.DoWork -= new DoWorkEventHandler(bg_DoWork); 
bg.Dispose(); 

これを呼び出した後、私はBackgroundWorkerがまだ動作していることがわかります。しかし、BackgroundWorkerの代わりにThreadを使用し、Abort()と呼んでも機能しません。どうしてこんなことに?バックグラウンドワーカーの処理対スレッド.abort

+0

あなたはそれが機能していないと言ったら、どういう意味ですか?タスクが完了する前にタスクを取り消そうとしていますか、タスクが完了したらバックグラウンドワーカー/スレッドを再利用しようとしていますか? – Sudsy1002

+0

私はスレッドをうまく終了できますが、backgroundworkerのdisposeを呼び出した後でコードブロックが停止していない間はtrueを返します。 –

+0

Disposeは、ネイティブコンポーネントをすべて解放します。 whileループはネイティブではないので、まだ実行中です – Steve

答えて

1

まあ、実際に、あなたは(while (true)break文またはreturnの文のような無限ループを停止し、明示的なコマンドを実装しなければならないためである)あなたのBackgroundWorkerに無限のタスクを割り当てています。

メソッドハンドラが(bg.RunWorkerAsync()の呼び出しによって)実行されると、あなたが何をしても実行され続けます。

イベントハンドラの登録を解除しても、ショーの虹の上のどこかに行かなければならないので、それを停止しません。

BackgroundWorkerインスタンスを削除しても、それを停止しません。 BackgroundWorkerクラスはComponentIDisposableインターフェイスを実装しています)から派生し、Dispose()メソッドを継承しますが、オーバーライドしません。その基本実装では、Component.Dispose()は、componentsコレクションからコンポーネントが削除され、Disposedイベントが発生することを許可しますが、作成中のスレッドは強制終了されません。

それが現在であるとして、あなたはBackgroundWorkerが停止することができます唯一の方法は、作成時にtrueにWorkerSupportsCancellationプロパティを設定してデザインを維持:

bg = new BackgroundWorker(); 
bg.WorkerSupportsCancellation = true; 

、その後の呼び出し:

bg.CancelAsync(); 

必要なとき。 Thread.Abort()のアプローチは避けてください。安全ではありません。

+0

私はこれを試しましたが、(true)実行中に停止しませんでした。 –

+0

イベントハンドラ内で 'CancellationPending'のチェックを実装する必要があるため、' void bg_DoWork(Object sender、DoWorkEventArgs e) { while(!bg.CancellationPending) DoSomething(); } ' –

+0

詳細については、次のURLを参照してください。https://stackoverflow.com/questions/6966573/how-is-backgroundworker-cancellationpending-thread-safe –

2

RunWorkerAsyncはスレッドを生成します。 Abort()を呼び出すと故意にこのスレッドが終了し、Dispose()はバックグラウンドワーカーインスタンスを破棄します。ワーカースレッドはこの処理から通知されず、幸いに実行を続行します。

BackgroundWorkerは、inherits from Componentというだけで使い捨てです。 Componentというディスポジションロジックは、コンテナとイベントハンドラのバインディングを処理しますが、BackgroundWorker自体は、廃棄するときれいになりません。

+0

この場合、backgroundworkerの実行を停止する唯一の方法は、boolをfalseに変更するだけですか? –

+0

afaikあなたは 'CancelAsync'を呼び出し、ワーカーメソッドの' CancellationPending'をポーリングします。[documentation](https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.cancelasync(v = vs .110).aspx) – dlatikay

0

BackgroundWorkerにはスレッドを中止するコードはありません(コードreferencesourceを確認できます)。スレッドを強制終了する代わりに、バックグラウンドジョブを適切にキャンセルする必要があります。たとえば、

while (!BackgroundWorker.CancellationPending) 
{ 
    label1.Text = DateTime.Now.Minute.ToString() + " " + DateTime.Now.Second.ToString(); 
} 
関連する問題