Wdrożenie asynchronicznego limitu czasu przy użyciu słabych asansów / oczekujących konstrukcji w .Net 4.0

Motywacja

Konstrukcje async / await C # 5.0 są niesamowite, ale niestety Microsoft pokazał tylko kandydata do wydania zarówno .NET 4.5, jak i VS 2012, a to zajmie trochę czasu, zanim te technologie zostaną powszechnie przyjęte w naszych projektach.

W Stephen Toub'sMetody asynchroniczne, iteratory C # i zadania Znalazłem zamiennik, który można ładnie wykorzystać w .NET 4.0. Istnieje również kilkanaście innych implementacji, które umożliwiają stosowanie tego podejścia nawet w .NET 2.0, choć wydają się one trochę przestarzałe i mniej bogate w funkcje.

Przykład

Tak wygląda teraz mój kod .NET 4.0 (skomentowane sekcje pokazują, jak to się robi w .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));
    }
}

Wygląda trochę brzydko, chociaż to działa

Pytanie

Podczas używaniaCancellationTokenSource w .NET 4.5 istnieje konstruktor, który przyjmuje czas trwania jako parametr limitu czasu, a więc wynikowyCancellationTokenSource anuluje w określonym czasie.
.Net 4.0 nie jest w stanie przekroczyć limitu czasu, więc jaki jest właściwy sposób wykonania tego w .Net 4.0?

questionAnswers(3)

yourAnswerToTheQuestion