thread.Abort
メソッドを使用してスレッドを強制終了していますが、機能していません。スレッドを終了する他の方法はありますか?
private void button1_Click(object sender, EventArgs e)
{
if (Receiver.IsAlive == true)
{
MessageBox.Show("Alive");
Receiver.Abort();
}
else
{
MessageBox.Show("Dead");
Receiver.Start();
}
}
これを使用していますが、Alive
ステータスを取得するたびに、Receiver
が私のグローバルスレッドです。
スレッドを強制終了するのが難しい理由は、言語設計者が次の問題を回避したいからです:スレッドはロックを取得し、それを解放する前に強制終了します。これで、そのロックが必要な人は誰でも行き詰まります。
あなたがしなければならないのは、スレッドに停止するよう指示するためにいくつかのグローバル変数を使用することです。スレッドコードで、そのグローバル変数を手動で確認し、停止する必要があることを確認したら戻る必要があります。
そのようにして即座に殺すことができます:
private Thread _myThread = new Thread(SomeThreadMethod);
private void SomeThreadMethod()
{
// do whatever you want
}
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
private void KillTheThread()
{
_myThread.Abort();
}
私はいつもそれを使用し、私のために働いています:)
最初に、スレッドを終了するための合意された方法が必要です。たとえば、スレッドがチェックして準拠できるrunning_変数。
メインスレッドコードは、終了時にスレッドをきれいに整頓するThreadInterruptExceptionとThreadAbortExceptionの両方をキャッチする例外ブロックでラップする必要があります。
ThreadInterruptExceptionの場合、running_変数をチェックして、続行する必要があるかどうかを確認できます。 ThreadAbortExceptionの場合は、すぐに整理してスレッドプロシージャを終了する必要があります。
スレッドを停止しようとするコードは次のことを行う必要があります。
running_ = false;
threadInstance_.Interrupt();
if(!threadInstance_.Join(2000)) { // or an agreed resonable time
threadInstance_.Abort();
}
スレッドは、作業が終了すると強制終了されます。そのため、ループなどを使用している場合は、スレッドに変数を渡して、スレッドが終了した後にループを停止する必要があります。
C#Thread.Abortは、スレッドを即座に中止することを保証しません。おそらく、スレッドがそれ自体でAbortを呼び出すときに機能しますが、スレッドが別のスレッドを呼び出すときは機能しません。
ドキュメントを参照してください: http://msdn.Microsoft.com/en-us/library/ty8d3wta.aspx
ハードウェアと相互作用するツールを書くこの問題に直面しました-あなたはすぐに停止したいが、それは保証されていません。私は通常、いくつかのフラグまたは他のそのようなロジックを使用して、スレッドで実行されているコードの一部の実行を防ぎます(そして、アボートで実行されたくない-トリッキーです)。
private void ResumeButton_Click(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() =>
{
Application.Current.Resources["AutoPilotThreadStatus"] = true;
Thread.CurrentThread.Name = "ResumeAutoPilot";
Thread.CurrentThread.IsBackground = true;
AutoPilotHandler.ResumeAutoPilot();
});
}
public static void ResumeAutoPilot()
{
while ((bool)Application.Current.Resources["AutoPilotThreadStatus"])
{
CheckAutoPilotThreadStatus();
var searchYoutube = YoutubeHandler.Search("small truck");
CheckAutoPilotThreadStatus();
SaveVideosToDatabase(searchYoutube);
CheckAutoPilotThreadStatus();
}
}
public static void CheckAutoPilotThreadStatus()
{
if (!(bool)Application.Current.Resources["AutoPilotThreadStatus"])
{
KillCurrentThread();
}
}
public static void KillCurrentThread()
{
Thread.CurrentThread.Abort();
}