Bikswan
Bikswan

Reputation: 140

How to write Timeoutable methods in C#

I have methods which take longer time to execute and involve lots of database operations. I want to wrap these methods within timeoutable method so that if it didn't callback within constant time, I will rollback.

Is there any way to do this, also I have to run the method in the main thread only becuase the 3rd party com objects I am using cannot be executed in background thread.

Any kind of suggestion will be highly appreciated.

regards,

Bibek Dawadi

Upvotes: 2

Views: 398

Answers (2)

plinth
plinth

Reputation: 49199

I knocked together a solution similar to the one linked to, except that I used Thread.Interrupt() instead of Thread.Abort(), thinking that would be a little kinder to the main thread. The problem is that Thread.Interrupt() won't interrupt a call that is blocked, so it is unsatisfactory under many cases. Thread.Abort() is a dangerous call and should be avoided where possible. Pick your poison.

For what it's worth, this is my implementation:

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();
        }
    }
}

For grins, I put in a timeoutAction so that you could use it in this mode:

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

Upvotes: 1

KeithS
KeithS

Reputation: 71591

I was with you till you said you needed it to run in the main thread. I don't think it's possible the way you describe.

The problem is that you're going to need at least two threads to perform the timing and the actual work, and neither of those can be the main thread because a timer won't use the main thread, and because you'll want the operation to terminate, which if it were the main thread would shut down the whole app. The way you would do this normally is to set up a wrapper class that is run from the main thread and sets up the background thread for the operation as well as the timer.

Why, exactly, does the 3rd party library have to be invoked from the main thread?

Upvotes: 1

Related Questions