Cross-Thread Exceptions in Asynchronous Programming
In synchronous programming (before async/await arrived on the scene) it was clear to me how or why cross-thread exceptions occurred. If I launched a background thread to do some heavy task so as to offload UI thread and make it responsive, I knew exactly what to do to access UI thread from the background thread. If in doubt I could even check in what thread a given code was executing.
With async/await asynchronous programming, I find what was a clear-cut identification of threads somehow blurred and murky (even well demonstrated in debugging with call stacks jumping all over the place based on numerous awaited tasks).
What I try to find out is a kind of roadmap that would help me identify cross-thread danger areas/pitfalls along the bumpy async/await meander (forgive the metaphor).
What, exactly, would I be watching for to avoid cross-thread exceptions when it comes to asynchronous programming? Can these be made into some kind of checklist?
I cover the main threading considerations in my async intro. To be specific, the default behavior of await is to capture a "context" and then resume the method within that "context". In the case of a UI thread, that context will cause the async method to resume on the UI thread.
So, plain async and await simply avoid most cross-threading concerns completely.
Note that if you do introduce background threads (e.g., Task.Run), then of course those background threads can cause cross-threading exceptions and you'll have to avoid those appropriately.