2011-10-12 10 views
8

Non ho avuto la possibilità di controllare il CTP della nuova funzionalità C# async/await, ma ecco qualcosa che mi stavo chiedendo:Come si integra la nuova funzione asincrona/attesa in C# 5 con il loop dei messaggi?

Come si integra con il loop dei messaggi? Presumo che in un'applicazione Windows standard (Winforms, WPF) le chiamate vengano inviate inviando messaggi al loop di messaggi dell'applicazione, utilizzando un Dispatcher o simile?

Cosa succede se non sto utilizzando un ciclo di messaggi standard di Windows? Ad esempio in un'applicazione GTK # o in un'applicazione console (se davvero questa funzionalità potrebbe essere utile in un'applicazione console).

Ho cercato su Internet per informazioni su questo, ma senza risultato. Qualcuno può spiegare?

risposta

5

Utilizza System.Threading.SynchronizationContext.Current. Sia WPF che Winform installano la propria versione di SynchronizationContext. Che usano il loro ciclo di messaggi per effettuare il marshalling della chiamata da un thread di lavoro al thread dell'interfaccia utente principale. Rispettivamente con Dispatcher.Begin/Invoke e Control.Begin/Invoke().

L'esecuzione di questa operazione in un'app della modalità Console non è semplice, il suo thread principale non ha uno stato "inattivo" ben definito che consente l'iniezione di chiamate al metodo di marshalling in modo sicuro, evitando mal di testa reentranza. Potresti certamente aggiungerlo, ma dovrai reinventare il ciclo dei messaggi.

+0

Grazie Hank. Cercando di pensare a una situazione in cui async sarebbe utile in un'applicazione console e in mancanza. Quindi penso che la mancanza di un contesto di sincronizzazione in questa situazione sia per lo più discutibile. – Grokys

+3

[AsyncEx] (http://nitoasyncex.codeplex.com/) include una classe [AsyncContext] (http://nitoasyncex.codeplex.com/wikipage?title=AsyncContext) che fornisce un ciclo principale asincrono compatibile per le app della console (e test unitari). –

+0

Ulteriori informazioni su 'SynchronizationContext' [qui] (http://msdn.microsoft.com/en-us/magazine/gg598924.aspx). –

4

Tutto si riduce a ciò che il "cameriere" fa con il seguito che è passato.

L'implementazione per Task<T> nel BCL utilizzerà il contesto di sincronizzazione corrente (unless you ask it not to using ConfigureAwait), che in WPF/SilverLight utilizzerà il dispatcher; in Windows Form userà qualcosa come Control.BeginInvoke, e in un thread pool di thread continuerà a essere eseguito su qualsiasi thread del thread. Tieni presente che è il tuo attuale contesto al punto dell'espressione di attesa che è importante, poiché è ciò che l'attività acquisirà per il proseguo dell'esecuzione.

Il post del blog collegato (di Mads Torgersen) fa un ottimo lavoro per spiegare come funziona tutto sotto il cofano, e ho un series of blog posts che potresti trovare utile anche.

+0

Grazie Jon. In tutte le mie escursioni su .Net land non mi sono mai imbattuto in SynchronizationContext.Current, che presumo tu intenda per "contesto di sincronizzazione attuale"? Impara qualcosa di nuovo ogni giorno. – Grokys

+1

@Groky: Sì. C'è dell'altro nell'articolo di Stephen Toub sulle prestazioni con async: http://msdn.microsoft.com/en-us/magazine/hh456402.aspx –

Problemi correlati