views:

141

answers:

5

How can i have any kind of data returned from a method or property within a time frame, and if any data is returned within that time frame an exception is thrown?

Pretty much I have a simple method that will perform a simple task, once performed the method returns a value, and if any value is returned within 100 milliseconds I want that the method be aborted and an exception be thrown, for instance a TimeoutException for example, any kind of exception, as long it does the task.

Thanks everyone.

+2  A: 

Look at WaitHandle and it's derivations. Should do what you want.

leppie
A: 

Well - you can start the method on a different thread and if thread does not return within stipulated time-frame then abort it. Although, if you are looking at very small time-frames then this way will have large overhead involved. (BTW, you can use Thread.Join overload for waiting stipulated time).

VinayC
+7  A: 

If you have access to .NET 4 I suggest you take a look at the new Task class. Create a Task with the work you want done and start this. The Wait method allows you to specify a timeout value. Wait returns a bool, so you know if the timeout occurred or not.

Brian Rasmussen
+4  A: 

If you are on .NET 3.5 and can't use Parallel Extensions, you can use asynchronous delegates. This has the added benefit of rethrowing exceptions thrown by the method on the calling thread. The timeout logic in this example relies on a WaitHandle, as mentioned by leppie.

public static T EvaluateAsync<T> (this Func<T> func, Timespan timeout)
{
  var result = func.BeginInvoke(null, null);

  if (!result.AsyncWaitHandle.WaitOne(timeout))
       throw new TimeoutException ("Operation did not complete on time.");

  return func.EndInvoke(result);
}

static void Example()
{
   var myMethod = new Func<int>(ExampleLongRunningMethod);

  // should return
  int result = myMethod.EvaluateAsync(TimeSpan.FromSeconds(2));

  // should throw
  int result2 = myMethod.EvaluateAsync(TimeSpan.FromMilliseconds(100));
}

static int ExampleLongRunningMethod()
{
  Thread.Sleep(1000);
  return 42;
}
Ani
@Ani: I've tried and this error appeared: Error 1 'System.Func<int>' does not contain a definition for 'EvaluateAsync' and no extension method 'EvaluateAsync' accepting a first argument of type 'System.Func<int>' could be found (are you missing a using directive or an assembly reference?) Any hint?
Fábio Antunes
@ Fábio Antunes: Put the EvaluateAsync method in a public static class in the same assembly as your calling code (or a referenced assembly), and make sure the namespace it resides in is included in the using statements in the file that contains the calling code.
Ani
@Ani: Thanks any. Worked pretty well Thanks.
Fábio Antunes
@Ani: Does the EvaluateAsync method needs to be static? I would like to use it in a regular method. Can it be done?
Fábio Antunes
@ Fábio Antunes: It does not need to be static, although there is no reason for it not to be. Note that it has been marked as an extension method, which allows you to pretend as though it is an instance method on `Func<T>`. You could still use it as a 'regular' method though.
Ani
@Ani: Thanks Ani its working pretty well.
Fábio Antunes