2009-08-25 17 views
41

thread.Abortメソッドを使用してスレッドを強制終了しますが、機能しません。スレッドを終了する他の方法はありますか?スレッドをC#で即座に削除するには?

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は私の世界的なスレッドです。

+10

危険、Will Robinson、危険! Thread.Abortを使うのは非常に恥ずかしがり屋です - ほとんど常に悪い考えです。 –

+4

スレッドを強制終了するにはどうすればよいですか? – Mobin

+3

スレッドに停止を依頼し、その時点のスレッドを無視します。 – MSalters

答えて

58

スレッドを殺すのが難しい理由は、言語設計者が次のような問題を回避したいからです。スレッドがロックをとり、解放する前にロックを解除するからです。そのロックを必要とする人は誰も拘束されません。

あなたがしなければならないことは、グローバル変数を使用してスレッドを停止させることです。スレッドコードで、手動でグローバル変数をチェックし、停止する必要があることがわかったらリターンしなければなりません。

+0

私はこのメカニズムを自分で使います。 UIベースのコードの場合はグローバル変数を設定し、サービスの場合はデータベーステーブルをチェックします。ニースと予測可能。 –

+5

可能であれば、変数の代わりにManualResetEventを使用してください。 –

+3

私は今興味があります - 早期終了条件をチェックするために、ManualResetEventはどのように優れていますか?私たちが何かをブロックしなければならない時には、彼らの方が優れていると理解していますが、ここではブロックされていません。 – redtuna

6

スレッドが終了するとスレッドが終了するので、ループなどを使用している場合は、変数をスレッドに渡してスレッドを終了してからループを停止する必要があります。

4

C#Thread.Abortは、スレッドを瞬時に中止することは保証されません。これはおそらくスレッドがAbortを呼び出すときには機能しますが、スレッドが別のスレッドを呼び出すときは機能しません。

は、ドキュメントを参照してください:http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx

私は、ハードウェアと対話するツールを書いて、この問題に直面している - あなたは即時停止をしたいが、それは保証されません。私は通常、スレッド上で実行されているコードの一部の実行を防ぐために、いくつかのフラグやその他のロジックを使用しています(そして、私は中断すると実行したくありません)。

14

まず、スレッドを終了するための合意された方法があります。たとえば、スレッドがチェックして遵守できる、実行可能な値。

メインスレッドコードは、終了時にスレッドをきれいに整理するThreadInterruptExceptionとThreadAbortExceptionの両方をキャッチする例外ブロックにラップする必要があります。

ThreadInterruptExceptionの場合は、running_変数を確認して続行する必要があるかどうかを確認できます。 ThreadAbortExceptionの場合、すぐに整理してスレッドプロシージャを終了する必要があります。

次の操作を行う必要があるスレッドを停止しようとするコード:

running_ = false; 
threadInstance_.Interrupt(); 
if(!threadInstance_.Join(2000)) { // or an agreed resonable time 
    threadInstance_.Abort(); 
} 
+2

これは私の考え方から唯一の受け入れ可能な答えです。はい、まずスレッドが終了するときに注意する変数が必要ですが、スレッド内でブロックしている場合は、その変数をチェックする機会はありません。ブロックされているスレッドを中断する別の方法が必要であり、この答えが私の問題を解決しました。ありがとう! – CramerTV

+0

'threadInstance_.Interrupt()'がスレッドを速く終了させた場合、 'threadInstance_.Join'は* System.Threading.ThreadStateExceptionをスローします:スレッドは開始されていません* – Hannobo

24

あなたはその方法でそれをやって即座に殺すことができます。

private Thread _myThread = new Thread(SomeThreadMethod); 

private void SomeThreadMethod() 
{ 
    // do whatever you want 
} 

[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] 
private void KillTheThread() 
{ 
    _myThread.Abort(); 
} 

は、私は常にそれを使用して私のために動作します: )

+0

しかしhttp://stackoverflow.com/a/1560567/199364を参照してください、およびthread.abortが危険な理由を説明するその他の回答 – ToolmakerSteve

+2

[Adrian Reganの答え](http://stackoverflow.com/a/1327377/199364)は、スレッドが死んでいない場合の最後の手段として、 'Abort'を使うもっと安全な方法です。 – ToolmakerSteve

-1
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(); 
    } 
+3

アプリリソースを使用しない方法の完全な例。 –

関連する問題