2009-04-02 6 views
5

私はさまざまなウェブサイトで、Thread.Abortがあまり使用しないことをよく読んでいます。この場合、どのようにタイムアウトパターンを実装しますか?例えば、私は、MSが以下のパターン(拡張メソッドでラップしたもの)をフレームワーク全体で使用していることを読んだことがあります。個人的には、これはかなり素晴らしい拡張機能だと思いますが、私はThread.Abortについて心配しています。誰か良い方法がありますか?タイムアウトパターン - Thread.Abortはどれくらい悪いですか?

public static bool CallandWait(this Action action, int timeout) 
    { 
     Thread subThread = null; 
     Action wrappedAction =() => 
     { 
      subThread = Thread.CurrentThread; 
      action(); 
     }; 

     IAsyncResult result = wrappedAction.BeginInvoke(null, null); 

     if (((timeout != -1) && !result.IsCompleted) && (!result.AsyncWaitHandle.WaitOne(timeout, false) || !result.IsCompleted)) 
     { 
      if (subThread != null) 
      { 
       subThread.Abort(); 
      } 

      return false; 
     } 
     else 
     { 
      wrappedAction.EndInvoke(result); 
      return true; 
     } 
    } 

答えて

10

潜在的に非常に悪いです。 "Managed code and asynchronous exception hardening":中止されたスレッドが破損している共有状態を残すことができる

、...

参照ジョーDuffyのブログを実行している非同期操作を残すことができます。

2

スレッドが不整合な状態になっているか、一部の作業の途中にあり、自分自身をクリアする機会がないために悪いです。

これを正しく閉じるには、メソッドを呼び出したりプロパティを設定したりして、アプリケーションの終了や他のタスクへの移動の前にThread.Joinが終了するまで待つようにします。

13

基本的には、(われわれが知っている限り)優雅なやり方で打ち切る方法はありません。

これは、の安全なの方法を中止することを意味します。 Thread.Abortは素晴らしいことではありません。様々な競争条件や醜い状況があります(Richard's answerのリンクを参照)。キャンセルについてわからない操作をキャンセルしたくないということを避けたいと願っています。もしあなたが絶対ににそれを行うには、があれば、後でアプリケーションを再起動することを検討してください。

関連する問題