Setting A Maximum Execution Time on a Thread

Scenario: You would like to be able to set a maximum execution time on a thread, and be able to exit and optionally return a failure condition if this time is exceeded.

You can use the WaitHandle.WaitOne overload that takes a timespan
parameter indicating the number of milliseconds to wait for completion as a simplified thread / method execution timeout mechanism.

Sample code:

using System;
using System.Threading;

class WaitOne
{
static AutoResetEvent autoEvent = new AutoResetEvent(false);

static void Main()
{
Console.WriteLine("Main starting.");

ThreadPool.QueueUserWorkItem(
new WaitCallback(WorkMethod), autoEvent);

// Wait for work method to signal.
if(autoEvent.WaitOne(new TimeSpan(0, 0, 1), false))
{
Console.WriteLine("Work method signaled.");
}
else
{
Console.WriteLine("Timed out waiting for work " +
"method to signal.");
}
Console.WriteLine("Main ending.");

Console.ReadLine();
}

static void WorkMethod(object stateInfo)
{
Console.WriteLine("Work starting.");

// Simulate time spent working.
Thread.Sleep(new Random((int)DateTime.Now.Ticks).Next(100, 2000));

// Signal that work is finished.
Console.WriteLine("Work ending.");
((AutoResetEvent)stateInfo).Set();
}
}


How does it work?

1) We create a new AutoResetEvent to be able to signal our thread, with its initial state being unsignaled (false)
2) We queue a new WorkItem onto a ThreadPool Thread, passing in a new WaitCallback pointing to our method that is to do the work, and passing the AutoReset Event as our State information.
3) We pass the WaitOne method of the AutoResetEvent as a boolean test, using the overloaded method that takes a TimeSpan timeout in milliseconds. This blocks the current thread until the WaitHandle is signaled, or times out. If signaled, that means the test will be true, and we know our work method completed before the timeout. If false,
we know that we have reached the specified timeout before our work method completed and was able to call the Set method of our AutoResetEvent, which was cast out of the object stateInfo that was a parameter to our workmethod.

You can even "wrap this all up" into a nice packaged method in a class if you like, where you would pass in the workmethod, any parameters, the timeout, and return a boolean to indicate success or timeout.

Your WaitCallback and Work Method must have the same parameters ( "object"), so if you need multiple parameters for your Work Method, you can wrap them up in the StateInfo parameter. For example you could pass an instance of a class that holds the various parameters and values you need, and in the callback method, cast the State object back to an instance of your class to retrieve your parameters.




Submission Date:  6/27/2006 5:32:42 PM
Submitted By:  Peter Bromberg
My Home Page:  http://www.eggheadcafe.com

By Peter Bromberg   Popularity  (333 Views)