如何在C#中编写Timeoutable方法

时间:2011-02-07 21:25:46

标签: c# methods timeout

我的方法需要更长的时间来执行并涉及大量的数据库操作。我想在超时方法中包装这些方法,这样如果它在常量时间内没有回调,我会回滚。

有没有办法做到这一点,我也必须在主线程中运行该方法只是因为我使用的第三方com对象无法在后台线程中执行。

任何建议都将受到高度赞赏。

的问候,

Bibek Dawadi

3 个答案:

答案 0 :(得分:2)

这应该有所帮助。

Implement C# Generic Timeout

答案 1 :(得分:1)

我和你在一起,直到你说你需要它在主线程中运行。我不认为你描述的方式是可能的。

问题是你需要至少两个线程来执行时间和实际工作,这些都不是主线程,因为计时器不会使用主线程,因为你'我希望操作终止,如果它是主线程将关闭整个应用程序。通常这样做的方法是设置一个从主线程运行的包装类,并为操作和计时器设置后台线程。

为什么确实必须从主线程调用第三方库?

答案 2 :(得分:1)

我敲了一个类似于链接的解决方案,除了我使用Thread.Interrupt()而不是Thread.Abort(),认为这对主线程来说有点小。问题是Thread.Interrupt()不会中断被阻止的调用,因此在许多情况下它是不能令人满意的。 Thread.Abort()是一个危险的调用,应该尽可能避免。选择你的毒药。

这是我的实施:

public static class AbortableProc
{

    public static void Execute(Action action, Action timeoutAction, int milli)
    {
        Thread currThread = Thread.CurrentThread;
        object stoppedLock = new object();
        bool stopped = false;
        bool interrupted = false;

        Thread timer = new Thread(() =>
        {
            Thread.Sleep(milli);
            lock (stoppedLock)
            {
                if (!stopped)
                {
                    currThread.Interrupt();
                    stopped = true;
                    interrupted = true;
                }
            }
        });
        timer.Start();

        try
        {
            action();
            lock (stoppedLock)
            {
                stopped = true;
            }
        }
        catch (ThreadInterruptedException)
        {
        }
        if (interrupted)
        {
            timeoutAction();
        }
    }
}

对于grins,我输入了timeoutAction,以便您可以在此模式下使用它:

AbortableProc.Execute(
    () => { Process(kStarting); Process(kWorking); Process(kCleaningUp); },
    () => { if (IsWorking()) CleanUp(); }
};