Ideally, you should use CancellationTokenSource
with timeout and observe its CancellationToken
inside your method. If that's not possible, you can use Task.WhenAny
. The following implementation of MethodAsync
should suit your scenario for .NET 4.0:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp
{
class Program
{
// the method to monitor and timeout
int Method()
{
Thread.Sleep(3000); // sleep for 3s
return 42;
}
Task<int> MethodAsync(int timeout)
{
// start the Method task
var task1 = Task.Run(() => Method());
// start the timeout task
var task2 = Task.Delay(timeout);
// either task1 or task2
return Task.WhenAny(task1, task2).ContinueWith((task) =>
{
if (task.Result == task1)
return task1.Result;
throw new TaskCanceledException();
});
}
// The entry of the console app
static void Main(string[] args)
{
try
{
// timeout in 6s
int result = new Program().MethodAsync(6000).Result;
Console.WriteLine("Result: " + result);
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
Console.WriteLine("Hit enter to exit.");
Console.ReadLine();
}
}
}
Below is the version of MethodAsync
using async/await
, if you can use Microsoft.Bcl.Async:
async Task<int> MethodAsync(int timeout)
{
// start the Method task
var task1 = Task.Run(() => Method());
// start the timeout task
var task2 = Task.Delay(timeout);
// either task1 or task2
var task = await TaskEx.WhenAny(task1, task2);
if (task == task1)
return task1.Result;
throw new TaskCanceledException();
}