Gary McGill
Gary McGill

Reputation: 27516

How can I get the continuation after an await to execute on the same thread?

As I recently discovered to my cost, doing an await when there's no synchronization context may result in the code after the await being executed on a different thread.

I'm currently having problems with strange behaviour in a VSTO office add-in, which I think is possibly a result of this behaviour. When processing events raised by the Office application, there's no synchronization context in place (unless I create a form, which will create a synchronization context).

My question is whether creating a form is the best / most efficient way to ensure that I have a synchronization context, or whether there's a simpler way to do it.

Upvotes: 5

Views: 854

Answers (2)

Stephen Cleary
Stephen Cleary

Reputation: 456517

Office apps do invoke their events in an STA context, but they do not provide an appropriate SynchronizationContext.

The easiest way to work around this is explained on my blog in SynchronizationContext Odds and Ends, where I briefly describe a couple of miscellaneous things that I found while doing research for my article but just weren't important enough to include. To fix this problem, at the beginning of every event, do this:

SynchronizationContext.SetSynchronizationContext(
    new WindowsFormsSynchronizationContext());

Any awaits after that should resume on the STA thread.

Upvotes: 5

Dan Bryant
Dan Bryant

Reputation: 27505

You might want to check out this article, which describes how to set up a SynchronizationContext without a message pump. Note that this is really only useful if you expect to have other work that you intend to await (queuing up multiple callbacks.) If you only ever await one thing at a time, your code might as well just run synchronously, since you don't have anything else to do with your idle time, like run a message pump.

Upvotes: 3

Related Questions