To answer the title question, "When is the Usage of ConfigureAwait(false)
in ViewModels problematic?" is "Never." Its use in a view model is irrelevant. What matters is what thread you want to run on after the async method is called, whether or not you are in a view model is irrelevant. The only time that using ConfigureAwait(false)
may be problematic is if you want to return to the thread that was running before the async method was called.
And for reference, docs on the SynchronizationContext class.
Maybe explaining what ConfigureAwait(false)
does is the best approach to answer this. When one calls an async method like so:
var x = await SomeMethodAsync();
var y = x;
The code var y = x
will run on the same thread that the work was being done on before the async method was called, i.e the Synchronization context prior to the async method call, however if you use ConfigureAwait(false), e.g.:
var x = await SomeMethodAsync().ConfigureAwait(false);
var y = x;
then the code var y = x
will run on the same thread that the SomeMethodAsync
method was running on when it returned. (Presumably SomeMethodAsync
uses Task.Run
or Thread.StartNew
which are the main ways of launching a new thread... await
does not start a new thread, it is only syntactic sugar to allow your async code to be more readable so that the code following the async method call does not have to be an a delegate method or lambda, but can be in-line just like synchronous code.)
So what you need depends on what might need to be updated. Any UI updates need to run on the Main or UI thread. You can always marshal code to the Main or UI thread with Device.BeginInvokeOnMainThread(Action)
.
Generally, when you are in a, let's say, button click handler event, the event handler method starts running on the UI thread. If you need to call one async method and then update some UI, then do not use ConfigureAwait(false)
so that after the async method you return to the Main/UI thread and you can update your UI. If you do not need to update any UI, then feel free to call ConfigureAwait(false)
so that you do not unnecessarily return to the UI thread when there is no need to be running on that thread.
In some cases if you are calling multiple async methods from one method that starts on the UI thread, you might want to use ConfigureAwait(false)
such that you are not going back and forth to the UI thread from background threads multiple times, which cause performance issues, but rather all of the Non-UI work is done on a background thread, and then you just manually marshal back to the UI thread when and if needed.
As for an ObservableCollection
, it does not have thread affinity, i.e. when an object can only be updated or modified on the same thread that it was created on, but it is also not thread safe, so your best plan is to only access or change the ObservableCollection on the same thread that it was created on, most likely he Main/UI thread.