19

特定のメソッドを実行するスレッドを作成しました。しかし、スレッドがまだ機能していても、スレッドを強制終了したい場合があります。これどうやってするの?Thread.Abort() を試しましたが、「スレッドが中止されました」というメッセージボックスが表示されます。私は何をすべきか?

4

8 に答える 8

49

電話しないでくださいThread.Abort()

Thread.Abort危険です。代わりに、平和的にシャットダウンできるように、スレッドに協力する必要があります。keepGoingスレッドは、たとえば、スレッドを停止するときに false に設定するブール値フラグを設定するなどして、それ自体を強制終了するように指示できるように設計する必要があります。スレッドには次のようなものがあります

while (keepGoing)
{
    /* Do work. */
}

Sleepスレッドがまたはでブロックする可能性がある場合は、Waitを呼び出してこれらの関数からスレッドを分割できますThread.Interrupt()。スレッドは、次を処理する準備ができている必要がありますThreadInterruptedException

try
{
    while (keepGoing)
    {
        /* Do work. */
    }
}
catch (ThreadInterruptedException exception)
{
    /* Clean up. */
}
于 2009-06-27T00:51:06.603 に答える
26

Abort() は、最後の手段としてのみ呼び出す必要があります。代わりに、変数を使用してこのスレッドを同期できます。

volatile bool shutdown = false;

void RunThread()
{
   while (!shutdown)
   {
      ...
   }
}

void StopThread()
{
   shutdown = true;
}

これにより、スレッドは実行していたことをきれいに終了し、アプリを既知の良好な状態に保つことができます。

于 2009-06-27T00:47:51.320 に答える
9

最も正確でスレッド セーフな方法は、WaitHandle を使用して、停止する必要があるときにスレッドに通知することです。主に ManualResetEvent を使用します。

スレッドには、次のものを含めることができます。

private void RunThread()
{
    while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100)))
    {
        // ...
    }
}

ここthis.flagで、ManualResetEvent のインスタンスです。this.flag.Set()これは、ループを停止するためにスレッドの外部から呼び出すことができることを意味します。

WaitOne メソッドは、フラグが設定されている場合にのみ true を返します。そうしないと、指定されたタイムアウト (例では 100 ミリ秒) 後にタイムアウトになり、スレッドはもう一度ループを実行します。

于 2009-06-27T06:20:14.967 に答える
7

スレッドを強制終了するのは得策ではありません。停止する必要があることを通知し、正常に終了させることをお勧めします。これにはさまざまな方法があります。

  • Thread.Interruptブロックされている場合は、それを突くために使用します。
  • フラグ変数をポーリングします。
  • WaitHandleクラスを使用してシグナルを送信します。

この回答ですでに行っているので、各メソッドの使用方法を再ハッシュする必要はありません。

于 2010-09-20T17:39:59.780 に答える
2

スレッドが中止された時点でスレッドが何をしていたかを判断できないため、スレッドを中止することは非常に悪い考えです。

代わりに、スレッドがチェックできるプロパティと、外部コードが設定できるプロパティを用意してください。終了しても安全な場所にあるときに、スレッドがこのブール値のプロパティをチェックできるようにします。

于 2009-06-27T00:49:04.470 に答える
2

私はジョンBに同意します

volatile bool shutdown = false;

void RunThread()
{

try
{
    while (!shutdown)
    {
        /* Do work. */
    }
}
catch (ThreadAbortException exception)
{
    /* Clean up. */
}
}

void StopThread()
{
   shutdown = true;
}
于 2012-05-19T11:55:38.167 に答える
1

WebServer クラスのスレッドを強制終了する例もあります...

https://net7ntcip.codeplex.com/SourceControl/changeset/view/89621#1752948

影響が何であるかを理解するだけでアボートは大丈夫だと思います...長時間実行されるタスクの前に状態を示している限り、アボートは機能しますが、(ShouldStop または ActionBranch など) などのフラグが必要です。

例をチェックしてください!

于 2012-05-19T11:59:18.040 に答える