2012-08-23 10 views
8

Sto provando a passare dal modello asincrono basato su eventi in cui ho monitorato i metodi di esecuzione utilizzando ID univoci e il gestore asynoperation.
Dato che questo è stato eliminato dalle App di Windows 8, sto cercando di ottenere un effetto simile con Async/Attesa, ma non riesco a capire come.
Quello che sto cercando di realizzare è qualcosa di simileCome monitorare se è in esecuzione un'attività asincrona/attendibile

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

La parte che sto lottando con è scoprire se il metodo è in esecuzione. Ho provato a creare un'attività e a controllare lo stato di entrambi e quello .status del metodo asincrono, ma non sembrano essere il posto giusto da guardare. Grazie

AGGIORNAMENTO: questo è il codice corrente che uso in .net 4 per ottenere lo stesso risultato. _updateMetaDataAsync è una classe basata sul modello asincrono basato su eventi.

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(); 
     } 
    } 

risposta

6

async/await è destinato a essere utilizzato per creare operazioni sequenziali eseguite in modo asincrono dal thread dell'interfaccia utente. Puoi farlo eseguire operazioni parallele, ma generalmente le operazioni "si aggiungono" al thread dell'interfaccia utente con una sorta di risultato. (c'è anche la possibilità di fare tipi "fire-and-forget" di operazioni asincrone con await ma non è raccomandato). Ad esempio, non c'è nulla di intrinseco a async/await per supportare la segnalazione dei progressi.

può esaurire il codice utilizzando async/await; ma è necessario utilizzare nuove interfacce di avanzamento come IProgress<T>. Per ulteriori informazioni sulla segnalazione dei progressi con async/await, vedere http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx. La migrazione a questo dovrebbe essere solo una questione di chiamare un delegato IProgress invece di un evento Progress.

+0

Non uso Async/Attendi tramite scelta, più perché MS ha disseminato l'API .net per Windows con Metodi marcati asincroni. Esiste comunque la possibilità di evitare di percorrere la rotta asincrona/attesa? – Oli

+3

Solo perché un metodo termina in Async non significa che devi usare 'await'. Puoi semplicemente usare il risultante 'Task' e fare tutto ciò che vuoi fare con esso, come ContinueWith. per esempio. 'webClient.DownloadStringAsync (myUri) .ContinueWith (t => Trace.WriteLine (" done "));' --no 'await'. –

2

Se stai usando un Task che hai creato, è possibile controllare la proprietà del Task Status (o semplicemente vedere Task.IsCompleted se il completamento è l'unico stato che ti interessa).

Detto questo, await non "restituirà" finché l'operazione non è completa, solleva un'eccezione o annulla. In linea di principio, puoi tranquillamente supporre che, se stai ancora aspettando "l'attesa", il tuo compito non è stato completato.

+0

Grazie Reed, potresti pubblicare del codice in quanto questo è esattamente quello che stavo cercando di fare, ma lo stato dice sempre WaitingForActivation anche se so che l'attività è in esecuzione. Fondamentalmente voglio 1 Attività dichiarata che posso quindi assegnare un metodo al costruttore. Da un altro metodo di classe posso quindi avviarlo e controllarne lo stato, anche se sentiti libero di indicare un modo migliore se ce n'è uno. – Oli

+0

@Oli In genere è una cattiva idea avere un Task che non è stato avviato - il TPL e async/await è orientato con il concetto di task sempre "hot", motivo per cui 'Task.Run' è preferito su' nuova attività ». Qual è l'obiettivo attuale qui? (Non i meccanismi, ma quello che stai cercando di realizzare) –

+0

Fondamentalmente ho una lunga attività che scarica informazioni da internet e aggiorna i dati sugli oggetti nell'applicazione. L'applicazione viene aggiornata quando vengono visualizzati nuovi oggetti e richiede l'esecuzione dell'attività. La mia logica .net 4 aveva una classe basata sul modello basato sugli eventi e aveva un'istanza della classe dichiarata (la chiamiamo methodasync) Quindi quando viene rilevato un nuovo oggetto chiama methodasync.IsTaskRunning (taskID).Non esegue l'operazione ma se è in esecuzione segna un bool che dice che deve essere eseguito di nuovo. Completato il methodasync, controlla bool e se "True" viene eseguito nuovamente. – 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 ** 
} 

Il bonus aggiuntivo è che è possibile vedere quanti oggetti sono seduti in coda!

Problemi correlati