Motivation
C# 5.0 async/await constructs are awesome, unfortunately yet Microsoft only shown a release candidate of both .NET 4.5 and VS 2012, and it will take some time until these technologies will get widely adopted in our projects.
In Stephen Toub's Asynchronous methods, C# iterators, and Tasks I've found a replacement that can be nicely used in .NET 4.0. There are also a dozen of other implementations that make it possible using the approach even in .NET 2.0 though they seem little outdated and less feature-rich.
Example
So now my .NET 4.0 code looks like (the commented sections show how it is done in .NET 4.5):
//private async Task ProcessMessageAsync()
private IEnumerable<Task> ProcessMessageAsync()
{
//var udpReceiveResult = await udpClient.ReceiveAsync();
var task = Task<UdpAsyncReceiveResult>
.Factory
.FromAsync(udpClient.BeginReceive, udpClient.EndReceive, null);
yield return task;
var udpReceiveResult = task.Result;
//... blah blah blah
if (message is BootstrapRequest)
{
var typedMessage = ((BootstrapRequest)(message));
// !!! .NET 4.0 has no overload for CancellationTokenSource that
// !!! takes timeout parameter :(
var cts
= new CancellationTokenSource(BootstrapResponseTimeout); // Error here
//... blah blah blah
// Say(messageIPEndPoint, responseMessage, cts.Token);
Task.Factory.Iterate(Say(messageIPEndPoint, responseMessage, cts.Token));
}
}
Looks little ugly though it does the job
The question
When using CancellationTokenSource in .NET 4.5 there is a constructor that takes timespan as a timeout parameter, so that resulting CancellationTokenSource
cancels within specified period of time.
.Net 4.0 is not able to timeout, so what is the correct way of doing that in .Net 4.0?
You can still use
CancelAfter()
, which is an extension method inMicrosoft.Bcl.Async
which is very similar to accepted answer above.This is the refereance souce code when I press F12 to see the implementation of
CancelAfter()
:Does this really have anything to do with async/await? Looks like you're just needing a way to cancel the token, independently of async/await, right? In that case, could you simply create a Timer that calls Cancel after the timeout?
EDIT
My initial response above is the basic idea, but a more robust solution is can be found in Is CancellationTokenSource.CancelAfter() leaky? (actually the .Net 4.5 implementation of the constructor you're seeking). Here's a function you can use to create timeout tokens based on that code.
FWIW, you can use async/await in 4.0 projects, just use the async targeting pack. Works Great For Me!