2013-10-11 18 views
3

我有一個偶爾掛起的方法(在一個DLL我不能修改,但必須使用)。如果我再次運行它通常會正常工作。我想知道是否可以創建一個後臺線程,等待20分鐘,然後在程序中拋出異常。我可以使用另一個線程檢測掛起的進程並從中恢復嗎?

var triesLeft = 5; 
while (triesLeft > 0) { 
    try { 
    var t = new Thread(() => { wait(20 minutes); throw new ApplicationHungException();}) 
    t.Start(); 
    Object o = MethodThatHangsForever10PercentOfTheTime(); 
    } catch (ApplicationHungException e) { 
    triesLeft--; 
    } 
} 
t.Abort(); 

這不起作用,因爲異常不會傳遞給它包含在try catch塊。有沒有一種方法可以讓我獲得線程給它的例外try catch塊?

+1

僅供參考,沒有「C#線程」這樣的東西。您似乎指的是.NET管理的線程。 –

+0

爲什麼你需要線程在這裏,只需將代碼放在「methodthathands」的位置 - 比你會發現異常 –

+0

@IlyaBursov'MethodThatHangsForever'來自我假設的DLL。 –

回答

1

你可以在一個單獨的線程你的工作,並等待20分鐘時間來完成:

var triesLeft = 5; 
while (triesLeft > 0) 
{ 
    var mre = new ManualResetEvent(false); 

    ThreadPool.QueueUserWorkItem(_ => { 
          MethodThatHangsForever10PercentOfTheTime(); 
          mre.Set(); 
        }); 

    if (mre.WaitOne(TimeSpan.FromMinutes(20))) 
    { 
      break; // Success! 
    } 
    triesLeft--; 
    } 
} 
+0

這是否總是等待20分鐘或mre.Set()導致它跳出while循環? – anthonybell

+0

@anthonybell'mre.Set()'會導致它立即崩潰。 –

+1

@anthonybell 20分鐘是最多等待的時間,然後它會從 –

1

一種方式做,這將掀起你的錯誤的方法在單獨的線程,並等待兩件事情之一發生;或者:

  • 的線程完成,或
  • 的預定時間量(例如,20分鐘)過去

一旦任一這些事情發生時,我們可以採取適當的行動。

的代碼會是這個樣子:

static void DoProcessing() { 
    var triesLeft = 5; 
    Object o = null; 

    while (triesLeft > 0) { 
     var t = new Thread(() => { o = MethodThatHangsForever10%OfTheTime(); }).Start(); 
     if (t.Join(new TimeSpan(0, 20, 0))) { 
      // The thread completed 
      break; 
     } else { 
      // We're out of time. 
      t.Abort(); // Important: See comments below about this 
      triesLeft--; 
     } 
    } 
} 

事實證明,中止線程是一個危險和脆弱的操作,如在下面的評論中指出裏德•科普塞。您的選擇是允許掛起的線程在其餘時間內(不管多長時間)活動,或者將Heisenbuggy方法調用隔離到單獨的進程。

然而,這會打開另一個蠕蟲,因爲你將不得不處理進程間通信,數據序列化和同步。這可能會也可能不值得,這是我留給你的判斷。

+0

Thread.Abort真的不是一個好主意 - 請參閱http://stackoverflow.com/q/1559255/65358 –

+0

@ReedCopsey我明白了。讓線程活出剩下的(可能是永久的)存在是否更好?還是有更好的方法來限制線程的使用壽命?我沒有很多多線程的經驗,請耐心等待。 –

+0

這真的取決於 - 一般來說,最好是解決問題(防止無限掛起),但Thread.Abort往往比讓線程永遠坐在那裏更糟......它可能會導致令人討厭的問題(請參閱多個在這個問題的答案) –

相關問題