实现 C# 通用超时 [英] Implement C# Generic Timeout

查看:44
本文介绍了实现 C# 通用超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找实现一种通用方式的好主意,使单行(或匿名委托)代码执行超时.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆