2012-08-23 17 views
8

Estoy tratando de hacer la transición desde el patrón asincrónico basado en eventos donde rastreé los métodos en ejecución usando identificadores únicos y el administrador de consultas.
Como esto se ha eliminado de las aplicaciones de Windows 8, intento obtener un efecto similar con Async/Await pero no puedo entender cómo.
Lo que estoy tratando de lograr es algo así comoCómo rastrear si se está ejecutando una tarea async/awaitable

private async Task updateSomething() 
{ 
    if(***the method is already running***) 
    { 
     runagain = true; 
    } 
    else 
    { 
     await someMethod(); 
     if (runagain) 
     { 
      run the method again 
     }    
    } 
} 

La parte Estoy luchando con es saber si el método se está ejecutando. Intenté crear una Tarea y ver el estado de ese y el estado. Del método asíncrono, pero no parecen ser el lugar correcto para buscar. Gracias

ACTUALIZACIÓN: Este es el código actual que uso en .net 4 para lograr el mismo resultado. _updateMetaDataAsync es una clase basada en el patrón asincrónico basado en eventos.

private void updateMetaData() 
    { 
     if (_updateMetaDataAsync.IsTaskRunning(_updateMetaDataGuid_CheckAllFiles)) 
     { 
      _updateMetaDataGuid_CheckAllFiles_Again = true; 
     } 
     else 
     { 
      _updateMetaDataGuid_CheckAllFiles_Again = false; 
      _updateMetaDataAsync.UpdateMetaDataAsync(_updateMetaDataGuid_CheckAllFiles); 
     } 
    } 

private void updateMetaDataCompleted(object sender, UpdateMetaDataCompletedEventArgs e) 
    { 
     if (_updateMetaDataGuid_CheckAllFiles_Again) 
     { 
      updateMetaData(); 
     } 
    } 

Respuesta

6

async/await está destinado a ser utilizado para crear operaciones secuenciales ejecutadas de forma asincrónica desde el hilo de la interfaz de usuario. Puede hacer que realice operaciones paralelas, pero generalmente las operaciones se "unen" de nuevo al subproceso de la interfaz de usuario con algún tipo de resultado. (También existe la posibilidad de realizar operaciones asincrónicas de tipo "disparar y olvidar" con await, pero no se recomienda). es decir, no hay nada inherente en async/await para admitir informes de progreso.

Usted puede obtener el progreso del código usando async/await; pero necesita usar nuevas interfaces de progreso como IProgress<T>. Para obtener más información sobre informes de progreso con async/await, consulte http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx. Migrar a esto solo debería ser una cuestión de llamar a un delegado IProgress en lugar de un evento Progress.

+0

No uso Async/Await por elección, más porque MS ha ensuciado el .net para Windows API con Métodos marcados con Async. ¿Hay alguna forma de evitar bajar por la ruta async/await? – Oli

+3

El hecho de que un método termine en Async no significa que tenga que usar 'await'. Simplemente puede usar la 'Tarea' resultante y hacer lo que quiera hacer con ella, como ContinueWith. p.ej. 'webClient.DownloadStringAsync (myUri) .ContinueWith (t => Trace.WriteLine (" done "));' --no 'await'. –

2

Si estás utilizando un Task que ha creado, se puede comprobar la propiedad del Grupo de Status (o simplemente ver Task.IsCompleted si la terminación es el único estado en el que está interesado en).

Dicho esto, await no "volverá" hasta que la operación finalice, genere una excepción o cancele. Básicamente, puede suponer que, si todavía está esperando el "esperar", su tarea no se ha completado.

+0

Gracias Reed, ¿Sería capaz de publicar algún código, ya que esto es exactamente lo que he estado tratando de hacer, pero el estado siempre dice WaitingForActivation aunque sé que la tarea se está ejecutando. Básicamente quiero 1 Tarea declarada que puedo asignar un método en el constructor. Desde otro método de clase, puedo iniciarlo y verificar su estado, aunque no dudes en señalar una forma mejor si la hay. – Oli

+0

@Oli En general, es una mala idea tener una tarea que no se haya iniciado: TPL y async/await están orientados al concepto de tareas siempre "calientes", por lo que 'Task.Run' se prefiere a' nueva tarea'. ¿Cuál es el objetivo real aquí? (No son los mecanismos, sino lo que intentas lograr) –

+0

Básicamente tengo una tarea larga que descarga información de Internet y actualiza datos sobre objetos en la aplicación. La aplicación se actualiza cuando aparecen nuevos objetos y solicita que se ejecute la tarea. Mi lógica .net 4 tenía una clase basada en el patrón basado en eventos y tenía una instancia de la clase declarada (vamos a llamarlo methodasync). Por lo tanto, cuando se detecta un nuevo objeto, llama a methodasync.IsTaskRunning (taskID).No ejecuta la tarea, pero si se está ejecutando, marca un bool que dice que necesita volver a ejecutarse. Cuando el metodasync finaliza, verifica ese bool y si es "Verdadero" se ejecuta nuevamente. – Oli

0
SemaphoreSlim queueToAccessQueue = new SemaphoreSlim(1); 
object queueLock = new object(); 
long queuedRequests = 0; 
Task _loadingTask; 
public void RetrieveItems() { 
    lock (queueLock) { 
     queuedRequests++; 
     if (queuedRequests == 1) { // 1 is the minimum size of the queue before another instance is queued 
     _loadingTask = _loadingTask?.ContinueWith(async() => { 
      RunTheMethodAgain(); 
      await queueToAccessQueue.WaitAsync(); 
      queuedRequests = 0; // indicates that the queue has been cleared; 
      queueToAccessQueue.Release() 
     }) ?? Task.Run(async() => { 
      RunTheMethodAgain(); 
      await queueToAccessQueue.WaitAsync(); 
      queuedRequests = 0; // indicates that the queue has been cleared; 
      queueToAccessQueue.Release(); 
     }); 
     } 
    } 
} 
public void RunTheMethodAgain() { 
    ** run the method again ** 
} 

¡La ventaja añadida es que puede ver cuántos elementos están esperando en la cola!

Cuestiones relacionadas