Implementing .Net method timeout
There are times when you want to do some kind of operation and set a timeout to it… say after 20 sec if there isn't an answer let me know… naturally if this operation is a database operation you have the connection or command timeout property that you can set but what if you are dealing with some operation that you don’t have such property or maybe you don’t even have control of…. such as 3rd party components.
Wouldn't it be lovely to be able to call some method setting a timeout to it and have it all in c# ? Well… it's pretty simple…
Let me start by thanking Mordy for his help in building this class... through it seems simple class we had some discussions if it would be better implementing the idea using async delegates or waiting on events.
Say you have SampleOperation which takes… undetermined amount of time… from 1-2sec to 20sec or maybe infinite… if something goes wrong…
class SampleObject
{
// illustrate waiting 4 seconds
Thread.Sleep(TimeSpan.FromSeconds(4));
// settings variables values during the operation
name="Ohad";
id=123;
return true;
}
}
This is how I it would be used…
static void
{
// declare the method watcher
WatchdogRunner wcr = new WatchdogRunner();
// start method with 3 sec timeout
if (wcr.DoIt(TimeSpan.FromSeconds(3)))
{
Console.WriteLine("success");
Console.WriteLine("name = {0}",wcr.name);
Console.WriteLine("id = {0}",wcr.id);
}
else
Console.WriteLine("failed");
Console.ReadLine();
}
And this is the Watchdog…
class WatchdogComRunner
{
// method SampleOperation return variables
public int id;
public string name;
// Notifies a waiting thread that an event has occurred
AutoResetEvent evnt = new AutoResetEvent(false);
public bool DoIt(TimeSpan timeout)
{
Thread th = new Thread(new ThreadStart(runComComponent));
// Sets the state of the specified event to non signaled.
evnt.Reset();
// start thread
th.Start();
// wait with timeout on the event
if (evnt.WaitOne(timeout,false))
{
Console.WriteLine(this.name);
// Sucess - timeout did not occurred
return true;
}
else
{
// Failure - Timeout - do cleanup
th.Abort();
return false;
}
}
void runComComponent()
{
// create sample object
SampleObject c = new SampleObject();
// run sample method with out parameters
c.SampleOperation(out name,out id);
// Sets the state of the specified event to signaled
evnt.Set();
}
}