1

BackgroundWorker長時間実行される外部操作の処理に使用しています。ただし、ユーザーにはバックグラウンド操作をキャンセルするオプションがあります。私のカスタム BackgroundWorker は をサポートしているので、Thread.Abort()私がしているのはBackgroundWorker.Abort()、ユーザーがメインスレッドからキャンセルをトリガーしたときだけです。

しかし、スレッドは実際には終了していません。まだ外部プロセスを完了しています。スレッドを即座に終了できる方法はありますか。

外部処理を制御できないため、 のようなアプローチのフラグを送信できませんwhile (checkThreadCancelled){}

以下は私の擬似コードです。

何か助けはありますか?

AbortableBackgroundWorker _bgWorker;

void MainThreadFunc()
{
    _bgWorker = new AbortableBackgroundWorker();
    _bgWorker.DoWork += new DoWorkEventHandler(bg_DoWork);
    _bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler
                    ( bg_RunWorkerCompleted );
    _bgWorker.WorkerSupportsCancellation = true; 
    _bgWorker.RunWorkerAsync();
}

void bg_DoWork()
{
    //Call external dll function for processing
}

void bg_RunWorkerCompleted()
{

   //Process completed code
}

void CancelBgProcess()
{
   if(_bgWorker != null)
      _bgWorker.Abort();
}
4

3 に答える 3

3

Abort メソッドは、それと連携するワーカー スレッドに依存しています。最終的に、CLR は、スレッドがアボートすることを示す例外をスローします。これは、スレッドが自由に処理できます。

ワーカー スレッドが DLL で何かを実行しているため、CLR は制御されていないため、例外をスローするオプションがありません。

Win32 TerminateThread API を使用することもできますが、これを行うと深刻な問題が発生し、プロセス内で破損が発生する場合と発生しない場合があります。TerminateThread は、実際には選択すべきオプションではありません。

呼び出しているライブラリを変更できないため、2 つのオプションが残されています。最初の最も簡単な方法は、バックグラウンド スレッドの優先順位を下げ、キャンセル後も引き続き実行されるという事実を無視することです。

2 つ目は、バックグラウンド操作をスレッドではなく別のプロセスで起動することです。その時点で、操作がキャンセルされた場合、プロセス全体を終了できます。この方法をとる場合、ライブラリの入力パラメータと出力パラメータを通信するために何らかの形式の IPC を選択する必要があります。

Tasks最終的CancellationTokensには、同じ場所にたどり着くため、この状況では役に立ちません。つまり、キャンセルするために協力しないライブラリコードを実行します。

于 2013-10-11T04:41:05.137 に答える
1

を使用したくないThread.Abort場合は、通常、悪い習慣と見なされます。SO については、非常に良い説明を提供する多くの質問があります。例:タイムアウト パターン - Thread.Abort は本当にどの程度悪いのか?

とを見てTasksくださいCancellationTokens。この MSDN の記事を参照してください: http://msdn.microsoft.com/en-us/library/dd997396.aspx

于 2013-10-11T04:33:43.497 に答える