9

最近、「クラシック」スレッドの代わりに backgroundworker を使用しようとしましたが、少なくとも私にとっては、解決策よりも多くの問題を引き起こしていることに気付きました。バックグラウンドワーカーが同期読み取り (この場合は serialPort から) を実行していて、1 つのコード行で約 30 秒ブロックされている場合、キャンセル保留は解決策ではありません。アプリケーションがこの時点で (十字ボタンと Application.Exit() のいずれかを使用して) 閉じられると、プロセスは永遠にゾンビのままになります。

強制的に中止するか、backgroundworker スレッドを強制終了する方法が必要です。

4

5 に答える 5

5

私は(私が思うに)仕事をするものをまとめました。私がオフになっている場合はお知らせください。これがどのように機能するかの簡単な例です。

var backgroundWorker = new BackgroundWorker(){WorkerSupportsCancellation = true};

backgroundWorker.DoWork += (sender, args) =>
         {                 
                 var thisWorker = sender as BackgroundWorker;
                 var _child = new Thread(() =>
                                               {
                                                   //..Do Some Code

                                               });
                 _child .Start();
                 while (_child.IsAlive)
                 {
                     if (thisWorker.CancellationPending)
                     {
                         _child.Abort();
                         args.Cancel = true;
                     }
                     Thread.SpinWait(1);
                 }                 
         };

 backgroundWorker.RunWorkerAsync(parameter);
 //..Do Something...
backgroundWorker.CancelAsync();

バックグラウンド ワーカーはスレッド プールの一部であるため、アボートしたくありません。しかし、アボートを発生させることができるスレッドを内部で実行することができます。その後、backgroundWorker は基本的に、子スレッドが完了するか、プロセスを強制終了するように通知するまで実行されます。その後、バックグラウンド ワーカー スレッドは読み取りプールに戻ることができます。通常、これをヘルパー クラスにラップし、バックグラウンド スレッドで実行するデリゲート メソッドをパラメーターとして渡し、それを子スレッドで実行します。

誰かが壁に頭をぶつけているかどうか教えてください..

于 2010-04-07T03:00:47.377 に答える
3

BackgroundWorkerスレッドは「バックグラウンド」としてマークされており、UIを閉じると終了するため、プロセスがゾンビになることはありません。

于 2009-07-06T15:32:51.287 に答える
2

BackgroundWorker がスレッドの強制終了をサポートしているとは思わない。操作のキャンセルは、ジョブを実行するメソッドで行う必要があります。あなたの場合、通常のスレッドが最良の選択肢になると思います。

于 2009-03-05T11:07:04.230 に答える
2

何を達成しようとしているのかよくわかりませんが、おそらくSerialPort.DataReceivedイベントの方が良い解決策でしょうか?

すでにスレッドの使用に習熟している場合は、BackgroundWorker を使用する意味がわかりません。そもそもスレッドを理解していない人向けに設計されています。

その上、スレッドを中止するという考えは好きではありません。それは危険に感じられ、マルチスレッド アプリケーションはこれ以上リスクを冒す必要はありません。

于 2009-03-05T11:10:38.213 に答える
0

これを試すことができます:

            backgroundworker.Dispose();
            backgroundworker = null;
            GC.Collect(); //this helps cleans up ram
于 2015-08-17T09:41:57.710 に答える