バックグラウンドワーカーの中止
-
03-07-2019 - |
質問
最近、「クラシック」の代わりにバックグラウンドワーカーを使用しようとしました。スレッドと私はそれが解決策よりも、少なくとも私のために、より多くの問題を引き起こしていることを実現しています。 同期読み取り(この場合はserialPortから)を実行しているバックグラウンドワーカーがいて、1コード行で約30秒ブロックされましたが、キャンセル保留は解決策ではありません。この時点でアプリケーションが閉じられると(クロスボタンとApplication.Exit()で)、プロセスはゾンビを永久に保持することがわかります。
強制終了またはバックグラウンドワーカースレッドを強制終了する方法が必要です。
解決
何を達成しようとしているのかよくわかりませんが、 SerialPort.DataReceived イベントはより良い解決策ですか?
既にスレッドの使用に習熟している場合、BackgroundWorkerを使用する意味はわかりません。そもそもスレッドを理解していない人向けに設計されています。
さらに、スレッドを中断するという考えは好きではありません。危険を感じており、マルチスレッドアプリケーションはリスクを取る必要がありません。
他のヒント
仕事をする(考えている)ものをまとめました。 im waaaay offがあれば教えてください。 仕組みの簡単な例を以下に示します。
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は、基本的に、子スレッドが完了するか、プロセスを強制終了するように通知するまで実行されます。その後、バックグラウンドワーカースレッドは読み取りプールに戻ることができます。通常、これをヘルパークラスでラップし、バックグラウンドスレッドがパラメーターとして渡され、子スレッドで実行されるようにするデリゲートメソッドを渡します。
誰かが私の頭を壁にぶつけているかどうかを教えてください。しかしそれはうまくいくようです。しかし、スレッドの問題はそれではありません。 p>
BackgroundWorkerスレッドは「バックグラウンド」としてマークされているため、プロセスがゾンビになることはありません。 UIが閉じられると終了します。
BackgroundWorkerがスレッドの強制終了をサポートしているとは思わない。操作のキャンセルは、ジョブを実行するメソッドで実行する必要があります。あなたの場合、通常のスレッドが最良の選択肢になると思います。
これを試すことができます:
backgroundworker.Dispose();
backgroundworker = null;
GC.Collect(); //this helps cleans up ram