2011-02-07 17 views
6

Ho una domanda su quale meccanismo si possa utilizzare per annullare un'operazione asincrona in corso, invece un token di cancellazione nel contesto async/await. Sono sicuro che questa è una decisione progettuale ben studiata che tiene conto della natura imperativa della lingua, ma in situazioni reali dover passare un oggetto di cancellazione a tutti i tuoi metodi asincroni è, almeno, un po 'doloroso. Ci sono altre idee di progettazione dalla comunità C#, oppure il meccanismo di cancellazione proposto è OK? Penso che mi manchi qualcosa.meccanismo di annullamento asincrono/attendi

+0

Il meccanismo di annullamento che utilizza un token di annullamento sembra essere la direzione verso cui si dirige, incluso nel C# 5 CTP su Async. http://msdn.microsoft.com/en-us/vstudio/gg316360. Non è la chiamata C# 5, ma la sto usando qui per indicare la "prossima" versione di C#. –

+0

Hai appena notato che hai usato "attendi" nella tua domanda in modo da avere familiarità con il CTP. Penso che la libreria Task Parallel Library (.NET 4) abbia confermato che le funzionalità fornite erano la strada da percorrere e quindi il CTP Async utilizza lo stesso paradigma. –

+0

Correlati: http://stackoverflow.com/q/4914374/60761 –

risposta

4

Il token di annullamento è la procedura consigliata, soprattutto quando il processo asincrono è costoso, non ha una condizione di fine preimpostata o coinvolge risorse esterne.

Tuttavia, è possibile, se lo si desidera, semplicemente "rinunciare". Invece di dire al thread async di interrompere l'elaborazione e pulire, solo "time out"; smettila di aspettare che si completi, rimuovi gli ascoltatori e continua a correre. Alla fine del thread, controllerà il suo evento, realizzerà che nessuno sta ascoltando e terminerà silenziosamente. Il vantaggio è la semplicità, tuttavia ci sono molte situazioni in cui questo sarebbe una cosa negativa:

  • Se il processo asincrona manterrà l'elaborazione per sempre a meno che non gli si dice di smettere, non mancherà di tenere in esecuzione in background, legando fino a CPU e altre risorse, fino a quando l'app non viene chiusa, momento in cui il thread verrà ucciso.
  • Se il thread asincrono sta eseguendo un'unità di lavoro reversibile, comoda come un'operazione DB, se l'utente preme Annulla, si aspetta che tutto ciò che è stato fatto fino ad ora sia stato ripristinato. Se smetti di ascoltare e vai avanti, ciò che otterranno è che ciò che pensavano di aver cancellato è stato eseguito.
  • Nella maggior parte dei casi, le operazioni asincrone coinvolgono risorse esterne che richiedono tempo per funzionare e richiedono anche una corretta pulizia. I socket di rete devono essere disconnessi, le connessioni DB chiuse, i file sbloccati, ecc. Benché rinunciare significa che non si ha a che fare con questo, lasciando che il thread finisca normalmente, un'esperienza utente comune è quella di essere stufo, colpire annullare e riprovare l'operazione. Ciò significa che la risorsa che hai usato nella precedente operazione asincrona deve essere rilasciata per usarla di nuovo.
1

Per annullare un'operazione asincrona, l'operazione deve eseguire passaggi discreti, poiché è in corso l'operazione per controllare il token di cancellazione e impedirsi di continuare. Cioè il token di cancellazione è semplicemente uno schema da implementare non un meccanismo di asincrono/attesa.

Che cosa significa che se l'operazione asincrona è una sola chiamata I/O con un handle di completamento, si potrebbe anche rinunciare piuttosto che annullare, poiché l'operazione non avrà l'opportunità di controllare il proprio token fino a quando quella chiamata ritorna a quel punto non c'è nulla da guadagnare.

Pertanto, quando si prende in considerazione un token di annullamento, considerare innanzitutto se questa operazione può essere resa più efficiente supportando la cancellazione o se non sia solo l'attesa per il completamento (ovvero utilizzando un meccanismo di timeout).

Problemi correlati