c# - 实现 C# 通用超时

标签 c# multithreading c#-3.0 asynchronous timeout

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

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

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

此外,如果可能的话,我希望停止进一步执行有问题的“超时”代码。

最佳答案

这里真正棘手的部分是通过将执行程序线程从 Action 传递回可以中止的位置来终止长时间运行的任务。我通过使用包装委托(delegate)来完成此操作,该委托(delegate)将要终止的线程传递到创建 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();
        }
    }

}

关于c# - 实现 C# 通用超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/299198/

相关文章:

c# - 如何将gridview与来自两个不同表的数据绑定(bind)C#

c# - INotifyPropertyChanged - 数据访问、业务或 UI 层

Java线程相当于Python线程守护进程模式

c# - 套接字接收缓冲区大小

c# - 将 orderby、Skip() 和 Take() 与 LINQ 一起使用时出现重复行

c# - LINQ 到 XML : Collapse mutliple levels to single list

c# - 流媒体库 FFmpeg、avlib、libav 等

c# - 在 Unity 中运行时设置法线贴图

multithreading - Hibernate 与 akka Actor 一起工作吗?

java - 为什么我的线程似乎总是空闲?