Consider the following code:
public class EventManager
{
public Task<string> GetResponseAsync(string request)
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
return new Task<string>( () =>
{
// send the request
this.Send(request);
// wait for the response until I've been cancelled or I timed out.
// this is important because I want to cancel my "wait" if either occur
// WHAT CODE CAN I WRITE HERE TO SEE IF THIS TASK HAS TIMED OUT?
// (see the example below)
//
// Note that I'm not talking about cancellation
// (tokenSource.Token.IsCancellationRequested)
return response;
}, tokenSource.Token);
}
}
public static void Main()
{
EventManager mgr = new EventManager();
Task<string> responseTask = mgr.GetResponseAsync("ping");
responseTask.Start();
if (responseTask.Wait(2000))
{
Console.WriteLine("Got response: " + responseTask.Result);
}
else
{
Console.WriteLine("Didn't get a response in time");
}
}
In this case, you won't.
If you want to be able to kill off a task that doesn't return in time, you need to pass in your cancellation token to the async call (vs. creating it inside that method) so you can signal for it to cancel from your caller (Main in this case).
You can't know if your
Task
timed out because it actually never times out in this sample. TheWait
API will block on theTask
completing or the specified time ellapsing. If the time ellapses nothing happens to theTask
itself, the caller ofWait
simply returns with false. TheTask
continues to run unchangedIf you want to communicate to the
Task
that you are no longer interested in it's results the best way is to use cancellation.Task does not inlcude timeout functionality out of the box. You can add that essentially by starting a Timer that will cancel the task after the timeout, if it hasn't already completed.
Joe Hoad provides an implementation at the Parallel FX Team blog that does this and covers several edge cases that one could easily overlook.