2010-09-07 11 views
17

Estoy intentando encadenar programáticamente operaciones asíncronas en C# 4, como Escrituras en un objeto Stream determinado. Originalmente hice esto "manualmente", conectando devoluciones de llamada de una operación a la siguiente, pero pensé que probaría la .NET 4 Task Parallel Library para ahorrarme el problema de reinventar la rueda concurrente.¿Cómo encadenar operaciones asíncronas con la biblioteca de tarea paralela en .NET 4?

Para empezar, envuelvo mis llamadas asíncronas en las tareas de este modo:

public static Task CreateWriteTask(Stream stream, byte[] data) 
{ 
    return Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, data, 0, data.Length, null); 
} 

continuaciones han hecho encadenar operaciones síncronas muy fácil (si me disculpa el nombre del método desafortunado):

public static Task ChainFlush(Stream stream, Task precedingTask) 
{ 
    return precedingTask.ContinueWith(x => stream.Flush()); 
} 

Pero no existe una versión del método Task.ContinueWith que acepte una operación asincrónica de la misma manera que TaskFactory.FromAsync.

Así, suponiendo que persisto con el uso de la TPL, lo que estoy buscando la correcta aplicación de este método:

public static Task ChainWrite(Stream stream, byte[] data, Task precedingTask) 
{ 
    //? 
} 
+0

TaskCreationOptions.AttachedToParent? –

Respuesta

12

Mi mejor idea hasta ahora es que la cadena de la creación de la nueva tarea de escritura , a continuación, utilizar el método de extensión Separar a girar de nuevo en Task<Task>Task:

public static Task ChainWrite(Stream stream, byte[] data, Task precedingTask) 
{ 
    return precedingTask.ContinueWith(x => CreateWriteTask(stream, data)).Unwrap(); 
} 
1

Trate ContinueWhenAll() o ContinueWhenAny() en lugar de ContinueWith(). Ver here.

+0

Aquí está el enlace de MSDN: - http://msdn.microsoft.com/en-us/library/dd997423.aspx – prashanth

+1

Referencias interesantes, pero en realidad no resuelven mi problema. ContinueWhenAll/Any no tiene sobrecargas para aceptar operaciones Async, solo Acción y Func . La implementación de Iterator en su enlace es una idea interesante y puedo adaptarla para otro problema con el que me he enfrentado, pero asume que estoy haciendo lo mismo una y otra vez, y es básicamente una forma iterativa de hacer lo que yo hago. Mencionado en mi respuesta existente (crear una tarea dentro de otra tarea). ¡Gracias de cualquier manera! – FacticiusVir

3

Por lo que yo lo entiendo, esta es una desafortunada consecuencia de no tener el control sobre cuándo comienza una tarea. Dado que nunca se sabe cuando una tarea se inicia, no puede haber una sobrecarga como

precedingTask.ContinueWith(Task nextTask) 

porque una vez creada, puede que ya se inició cuando se llega a 'ContinueWith'. Además, también sería un desastre de tipos. ¿Cuál debería ser el tipo aquí:

precedingTask<T>.ContinueWith(Task<..what?..> nextTask) 

anterior devuelve una T, entonces ¿qué toma y qué devuelve? :) Esto podría resolverse con cierres sin embargo.

Cuestiones relacionadas