Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

await does not resume on original context

await for some reason does not seem to resume on the calling context. I'm calling an async method (actually a hierarchy of several async methods). Things go fine till I finally reaches the DataService which uses RestSharp's ExecuteAsync(). That final call looks like this:

IRestResponse Response = await rc.ExecuteAsync(request); //rc is a RestClient object

I have debugged it thoroughly and at each level, the following line returns true, even just before calling ExecuteAsync:

System.Threading.Thread.CurrentThread == System.Windows.Application.Current.Dispatcher.Thread

Only after the ExecuteAsync() returns with server data, the above line becomes false, indicating that the above await did not resume on the calling thread. Thereupon, the higher layers that called this async operation and now want to assign returned data to the UI throw the infamous STA thread exception.

What am I doing wrong? I have burnt several hours already and gone through several SO posts and web articles, but this doesn't seem to work. I have also added ConfigureAwait(true) to explicitly ask it to resume on calling context, but it didn't.

This is a VSTO Word add-in. I'm using it with WPF.

like image 408
dotNET Avatar asked Mar 02 '23 20:03

dotNET


1 Answers

This is a VSTO Word add-in.

This is actually the source of the problem.

The actual "context" captured by the await is SynchronizationContext.Current (unless it is null, in which case it is TaskScheduler.Current). UI apps like WinForms and WPF provide their own SynchronizationContext, which is how await resumes on the UI thread.

Except Office add-ins. I'm not sure why, but they do not provide a SynchronizationContext. So if you want to use await in an Office add-in, you'll need to supply the SynchronizationContext.

I believe a WPF-based Office add-in would be able to do this at the beginning of every async event:

SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext());

But I have never actually tried this. :)

like image 195
Stephen Cleary Avatar answered Mar 04 '23 10:03

Stephen Cleary