2

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

Bikswan
  • 141
  • 11
  • Unless someone has a better idea, I would think a method attribute might be in order. Otherwise, tasking with timer or other design suggestion. – IAbstract Feb 07 '11 at 21:29

2 Answers2

1

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?

KeithS
  • 70,210
  • 21
  • 112
  • 164
  • Doing the heavy lifting in the main thread is possible, but should be avoided if you can. However, another thread is indeed required unless the main thread is constantly checking itself. – Telavian Feb 07 '11 at 22:41
  • I am using Outook API and some how it is not working consistently when being called from backgroud thread. Microsoft support recommended to call API from main thread only and that is working for me now and I dont have other option. – Bikswan Feb 08 '11 at 20:58
  • Actaully, I am working on master/slave distributed system where master will be assigning some job to slave and after some predicted interval if slave cannot finish the job master will assume that some error occured on slave and do whatever is necessary to addess this. I dont know if any option is avaiable in programming world if not through timeoutable methods. – Bikswan Feb 08 '11 at 21:04
1

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(); }
};
plinth
  • 48,267
  • 11
  • 78
  • 120