2012-10-05 7 views
5

Come ho scoperto di recente, fare un await quando non c'è un contesto di sincronizzazione può causare il codice dopo l'attesa di essere eseguito su un thread diverso.Come posso ottenere la continuazione dopo un'attesa da eseguire sullo stesso thread?

Attualmente sto riscontrando problemi con un comportamento strano in un componente aggiuntivo di Office VSTO, che penso sia probabilmente il risultato di questo comportamento. Durante l'elaborazione degli eventi generati dall'applicazione di Office, non è presente alcun contesto di sincronizzazione (a meno che non crei un modulo, che creerà un contesto di sincronizzazione).

La mia domanda è se creare un modulo è il modo migliore/più efficace per garantire che disponga di un contesto di sincronizzazione o se esiste un modo più semplice per farlo.

+0

Non sarebbe più semplice non utilizzare "attendere" in questo caso? Se l'API che stai usando è solo asincrona, puoi ottenerla usando 'Result' o' Wait() '. – svick

+0

@svick: Credo che quello che stai dicendo sia che se voglio che l'atteso torni sullo stesso thread, allora è un comportamento effettivamente "sincrono". Hmmm ... sì, immagino lo sia. *Sospiro*. Sono un po 'perso con questa roba, a dire il vero. –

risposta

5

Le app di Office invocano i loro eventi in un contesto STA, ma non forniscono uno SynchronizationContext appropriato.

Il modo più semplice per ovviare a questo problema è spiegato sul mio blog in SynchronizationContext Odds and Ends, dove descrivo brevemente un paio di cose varie che ho trovato mentre facevo ricerche per il mio articolo, ma che non erano abbastanza importanti da includere. Per risolvere questo problema, all'inizio di ogni evento, fare questo:

SynchronizationContext.SetSynchronizationContext(
    new WindowsFormsSynchronizationContext()); 

Qualsiasi await s dopo che dovrebbero riprendere sul thread STA.

+0

Nota per chiunque pensi di fare questo - vedi anche http://stackoverflow.com/q/12898569/98422 –

3

Si potrebbe voler verificare this article, che descrive come impostare un SynchronizationContext senza un messaggio pompa. Si noti che questo è davvero utile solo se si prevede di avere altro lavoro che si intende attendere (accodamento di più callback). Se si attende solo una cosa alla volta, il codice potrebbe anche funzionare in sincrono, dal momento che non si Ho altro da fare con il tuo tempo di inattività, come eseguire un message pump.

Problemi correlati