10

Estoy tratando de implementar un TrackingParticipant personalizado para WF 4. Puedo escribir el método Track, pero mi implementación será lenta.Implementar el patrón Async clásico con TPL

¿Cómo puedo implementar las anulaciones de Begin/EndTrack con la Biblioteca de tareas paralelas (TPL) de .NET 4.0? Miré TPL and Traditional .NET Asynchronous Programming pero no estoy seguro de cómo aplicarlo aquí.

Tenga en cuenta que TrackingParticipant es parte de .NET y tiene el Patrón Async clásico predefinido mediante métodos virtuales.

public class MyTrackingParticipant : TrackingParticipant 
{ 
    protected override IAsyncResult BeginTrack(
     TrackingRecord record, TimeSpan timeout, 
     AsyncCallback callback, object state) 
    { 
     // ? 
    } 

    protected override void EndTrack(IAsyncResult result) 
    { 
     // ? 
    } 

    protected override void Track(TrackingRecord record, TimeSpan timeout) 
    { 
     // synchronous code to be called 
    } 
} 

Respuesta

18

Este es el patrón genérico con el que al aplicar el modelo de programación APM clásica:

protected override IAsyncResult BeginTrack(TrackingRecord record, TimeSpan timeout, AsyncCallback callback, object state) 
{ 
    Task result = Task.Factory.StartNew(
     (taskState) => 
     { 
      // ... your async work here ... 
     }, 
     state); 

    if(callback != null) 
    { 
     result.ContinueWith((t) => callback(t)); 
    } 

    return result; 
} 

protected override void EndTrack(IAsyncResult asyncResult) 
{ 
    // Call wait to block until task is complete and/or cause any exceptions that occurred to propagate to the caller 
    ((Task)asyncResult).Wait(); 
} 

Si el método EndXXX devuelve un resultado que en realidad devolver la propiedad Result del Task en lugar de simplemente llamando Wait. Por ejemplo:

protected override int EndAwesomeCalculation(IAsyncResult asyncResult) 
{ 
    // This will block until the result is available and/or cause any exceptions that occurred propagate to the caller 
    return ((Task<int>)asyncResult).Result; 
} 
+0

¡Gracias! Esto funciona; Curiosamente, el flujo de trabajo sigue bloqueado hasta que se completa Track(). (Llama los métodos Begin/End.) Parece que tendría que implementar una cola para obtener el comportamiento que quiero. (¡No restar valor a tu respuesta correcta!) – TrueWill

Cuestiones relacionadas