2013-10-11 15 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往往比让线程永远坐在那里更糟......它可能会导致令人讨厌的问题(请参阅多个在这个问题的答案) –

相关问题