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.
The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active.
Async/await helps you write synchronous-looking JavaScript code that works asynchronously. Await is in an async function to ensure that all promises that are returned in the function are synchronized. With async/await, there's no use of callbacks.
Asynchronous MethodsWhen the executing thread reaches an await expression, it hits the “pause” button and the method execution is suspended. When the task being awaited completes, it hits the “play” button, and the method execution is resumed.
Delay will create a task which will complete after a time delay. Task. Delay is not blocking the calling thread so the UI will remain responsive.
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 await
s after that should resume on the STA thread.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With