题
我有一个功能,我希望允许运行为一定长度的时间,然后,如果它还没有放弃它自己的,中止。 什么是最好的方式做到这一点?
好的,我想过将来运行它在另外一个线程,等待与超时为其死亡,然后用 Thread.Abort()
杀了它(这可能不会工作如果能有一种错误的 catch
块)。另一选项(一个,我不知道如何做的工作)将一些种先发制人的计时器有一个扔在。
是否有一个更好的办法?一种简单的沙盒系统?
编辑: 功能我要运行没有任何系统的检查,如果它应该取消,我不能(如在 必须不)添加。此外,这一测试用具的种类如此的条件下,我将被杀害的功能是,它具有横行.在这种情况下,我不能指望它做什么正确。
解决方案
它可能是一个比过这样的事情,但你可以看看您是否要负荷,无论是托管线进入一个程序域.一个程序域基本上是一个.净沙箱。
如果该线变成杂草你可以杀死域.
其他提示
什么你想要实现的是一个 BackgroundWorker
.的 BackgroundWorker
可以执行的背景操作和提供机制,用于通知这一背景下运作的消除。
背景操作应当定期检查的 Cancel
财产上通过在 DoWorkEventArgs
实例并优雅地杀死自己,如果价值是 true
.
设置的取消的财产上的 DoWorkEventArgs
实例可以通过调用 CancelAsync
方法上的发起 BackgroundWorker
实例。
有一个很好的例子中 MSDN文件.也看到社区的贡献和相关的底部的链接,该网页。
你也可以找到这篇文章很有趣,它使用螺纹。中止,虽然我真的会让你避免... C#集方法的超时使用仿制药
在你的一切力量来寻找一个理智的解决这个问题。异常不是流动的控制,并线中止是哦那么糟糕得多。这就是说,你可以上运行一个线程和中止的线后超时。
编辑:这里是一个强烈的措辞,但是有效的,解释的只是多少我鼓励你找到另一解决方案: http://tdanecker.blogspot.com/2007/08/do-never-ever-use-threadabort.html
为什么不退出?什么样的结果,它不会产生?
我的第一次尝试将使够紧密码和处理的所有"坚持"的情况下所以你不需要一个看门狗-如果你是在等待资源得到释放,把超时在等待,以及处理例外情况适当。
短短的这个,我试图产生一个进程的看门狗,这样做的过程。杀了必要的。这是更有效的螺纹。中止--如果你们要为残酷的解决方案的方式,为什么不去?
我可能不了解问题是否正确,但为什么不能把逻辑进入功能本身?例如(C#):
public void someLongFunction()
{
DateTime start = DateTime.Now;
while (DateTime.Now <= start.AddMinutes(5)) // assuming 5 mins run time
{
// long processing code here
if (DateTime.Now > start.AddMinutes(5))
break;
// more long processing code
}
// thread clean up etc. here
}
如果你可以不中断地对过程的功能,可能需要使用一定时终止目前的螺纹(它避免了你执行你的职能在另外一个线程)。尽快前线程被中止,你resert这种中止的螺纹。ResetAbort()以及可以执行的其他步骤的程序。
所以你可以用一个类似于这一个
using System.Threading;
using System.Timers;
namespace tools
{
public class ThreadAbortTimer
{
public ThreadAbortTimer(int timeout)
{
_CurrentThread = Thread.CurrentThread;
_Timer = new System.Timers.Timer();
_Timer.Elapsed += _Timer_Elapsed;
_Timer.Interval = timeout;
_Timer.Enable = true;
}
/// <summary>
/// catch the timeout : if the current thread is still valid, it is aborted
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void _Timer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (typeof(ThreadAbortTimer))
{
if (_CurrentThread != null)
{
_CurrentThread.Abort();
_CurrentThread = null;
}
}
}
/// <summary>
/// timer that will check if the process lasts less than 30 seconds
/// </summary>
private readonly System.Timers.Timer _Timer;
/// <summary>
/// current thread to abort if the process is longer than 30 sec
/// </summary>
private Thread _CurrentThread;
/// <summary>
/// stop the timer
/// </summary>
public void Disable()
{
lock (typeof(ThreadAbortTimer))
{
_Timer.Enabled = false;
_CurrentThread = null;
}
}
/// <summary>
/// dispose the timer
/// </summary>
public void Dispose()
{
_Timer.Dispose();
}
}
}
然后你可以用这样的:
using (var timer = new ThreadAbortTimer(timeout))
{
try
{
// the process you want to timeout
}
catch
{
timer.Disable();
Thread.ResetAbort();
}
}
你可以使用线。Join()限制线执行。
我知道这可能看起来像矫枉过正,但它可以在技术上的工作你想要的方式。分裂的代码,你的工作,在2.第一部分将是一个管理和第二a部分的执行者。
的遗嘱执行人(在你的情况)可能是一个简单的命令行程序有什么功能你想要测试。什么,你的经理应用程序并在这一点是调用命令行程序过程中使用(系统。诊断)类。其中一种方法的过程类WaitForExit,这将等待您的主机应用程序,以退出。但如果应用程序不会退出,你可以指定一个时间之前要等待迫使该应用程序退出。
使用这你应该能得到你想要什么