Implementación de un tiempo de espera asíncrono utilizando construcciones de async / await de mans pobres en .Net 4.0

Motivación

Las construcciones asíncronas / esperadas de C # 5.0 son impresionantes, desafortunadamente, Microsoft solo mostró un lanzamiento de versión tanto de .NET 4.5 como de VS 2012, y tomará un tiempo hasta que estas tecnologías se adopten ampliamente en nuestros proyectos.

En Stephen Toub'sMétodos asíncronos, iteradores de C # y tareas He encontrado un reemplazo que se puede usar muy bien en .NET 4.0. También hay una docena de otras implementaciones que hacen posible el uso del enfoque incluso en .NET 2.0, aunque parecen poco obsoletas y menos ricas en características.

Ejemplo

Así que ahora mi código .NET 4.0 parece (las secciones comentadas muestran cómo se hace en .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));
    }
}

Parece poco feo aunque hace el trabajo

La pregunta

Cuando usasCancelaciónTokenSource en .NET 4.5 hay un constructor que toma el intervalo de tiempo como un parámetro de tiempo de espera, de modo que el resultadoCancellationTokenSource cancela dentro de un período de tiempo especificado.
.Net 4.0 no puede agotarse el tiempo de espera, ¿cuál es la forma correcta de hacerlo en .Net 4.0?

Respuestas a la pregunta(3)

Su respuesta a la pregunta