实现 C# 通用超时 [英] Implement C# Generic Timeout
问题描述
我正在寻找实现一种通用方式的好主意,使单行(或匿名委托)代码执行超时.
I am looking for good ideas for implementing a generic way to have a single line (or anonymous delegate) of code execute with a timeout.
TemperamentalClass tc = new TemperamentalClass();
tc.DoSomething(); // normally runs in 30 sec. Want to error at 1 min
我正在寻找一种可以在我的代码与不稳定代码(我无法更改)交互的许多地方优雅地实现的解决方案.
I'm looking for a solution that can elegantly be implemented in many places where my code interacts with temperamental code (that I can't change).
此外,如果可能,我希望有问题的超时"代码停止执行.
In addition, I would like to have the offending "timed out" code stopped from executing further if possible.
推荐答案
这里真正棘手的部分是通过将执行器线程从 Action 传递回可以中止的位置来终止长时间运行的任务.我通过使用包装的委托完成了这一点,该委托将要杀死的线程传递到创建 lambda 的方法中的局部变量中.
The really tricky part here was killing the long running task through passing the executor thread from the Action back to a place where it could be aborted. I accomplished this with the use of a wrapped delegate that passes out the thread to kill into a local variable in the method that created the lambda.
我提交了这个例子,供您欣赏.您真正感兴趣的方法是 CallWithTimeout.这将通过中止并吞下 ThreadAbortException 来取消长时间运行的线程:
I submit this example, for your enjoyment. The method you are really interested in is CallWithTimeout. This will cancel the long running thread by aborting it, and swallowing the ThreadAbortException:
用法:
class Program
{
static void Main(string[] args)
{
//try the five second method with a 6 second timeout
CallWithTimeout(FiveSecondMethod, 6000);
//try the five second method with a 4 second timeout
//this will throw a timeout exception
CallWithTimeout(FiveSecondMethod, 4000);
}
static void FiveSecondMethod()
{
Thread.Sleep(5000);
}
执行工作的静态方法:
static void CallWithTimeout(Action action, int timeoutMilliseconds)
{
Thread threadToKill = null;
Action wrappedAction = () =>
{
threadToKill = Thread.CurrentThread;
try
{
action();
}
catch(ThreadAbortException ex){
Thread.ResetAbort();// cancel hard aborting, lets to finish it nicely.
}
};
IAsyncResult result = wrappedAction.BeginInvoke(null, null);
if (result.AsyncWaitHandle.WaitOne(timeoutMilliseconds))
{
wrappedAction.EndInvoke(result);
}
else
{
threadToKill.Abort();
throw new TimeoutException();
}
}
}
这篇关于实现 C# 通用超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!