2012-10-05 7 views
5

Como descubrí recientemente a mi costa, hacer un await cuando no hay contexto de sincronización puede dar como resultado el código después de que se espera que se ejecute en un hilo diferente.¿Cómo puedo obtener la continuación después de una espera para ejecutar en el mismo hilo?

Actualmente estoy teniendo problemas de comportamiento extraño en un complemento de oficina VSTO, lo que creo que es posiblemente el resultado de este comportamiento. Al procesar eventos generados por la aplicación de Office, no existe un contexto de sincronización en su lugar (a menos que cree un formulario, lo que creará un contexto de sincronización).

Mi pregunta es si la creación de un formulario es la mejor/la manera más eficiente de garantizar que tengo un contexto de sincronización, o si hay una manera más simple de hacerlo.

+0

¿No sería más fácil no usar 'await' en este caso? Si la API que está utilizando es solo asincrónica, puede lograr eso utilizando el 'Resultado' de' Task' o 'Wait()'. – svick

+0

@svick: Supongo que lo que estás diciendo es que si quiero esperar para volver al mismo hilo, entonces ese es un comportamiento efectivamente "sincrónico". Hmmm ... sí, creo que es. *Suspiro*. Estoy un poco perdido con estas cosas, para ser sincero. –

Respuesta

5

Las aplicaciones de Office invocan sus eventos en un contexto STA, pero no proporcionan un SynchronizationContext apropiado.

La forma más fácil de evitar esto se explica en mi blog en SynchronizationContext Odds and Ends, donde describo brevemente un par de cosas diversas que encontré mientras investigaba para mi artículo pero que no eran lo suficientemente importantes como para incluirlas. Para solucionar este problema, al comienzo de cada evento, hacer esto:

SynchronizationContext.SetSynchronizationContext(
    new WindowsFormsSynchronizationContext()); 

Cualquier await s después de que se reanuden en el subproceso STA.

+0

Nota para todos los que estén pensando en hacer esto: consulte también http://stackoverflow.com/q/12898569/98422 –

3

Es posible que desee comprobar this article, que describe cómo configurar un SynchronizationContext sin una bomba de mensajes. Ten en cuenta que esto solo es útil si esperas tener otro trabajo que quieras esperar (hacer cola para varias devoluciones de llamada). Si solo esperas una cosa a la vez, tu código también podría ejecutarse sincrónicamente, ya que no lo haces. Tiene algo más que ver con su tiempo de inactividad, como ejecutar una bomba de mensajes.

Cuestiones relacionadas