一尘不染

实现C#通用超时

c#

我正在寻找实现通用方法以使单行(或匿名委托)代码超时执行的好主意。

TemperamentalClass tc = new TemperamentalClass();
tc.DoSomething();  // normally runs in 30 sec.  Want to error at 1 min

我正在寻找一种可以在我的代码与气质代码进行交互的许多地方优雅地实现的解决方案(我无法更改)。

另外,如果可能的话,我想阻止令人讨厌的“超时”代码进一步执行。


阅读 521

收藏
2020-05-19

共1个答案

一尘不染

这里真正棘手的部分是通过将执行程序线程从Action传递回可能中止的位置来杀死长期运行的任务。我通过使用包装的委托来完成此任务,该委托将线程传递出去以杀死生成lambda的方法中的局部变量。

我提交了这个示例,供您欣赏。您真正感兴趣的方法是CallWithTimeout。
这将通过中断长时间运行的线程并吞下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();
        }
    }

}
2020-05-19