Concurrency & Threading

5 questions found

Each platform has a single main/UI thread that owns the visual tree; touching UI from another thread causes exceptions or corruption. Async I/O runs off the UI thread, but results that mutate UI must be marshaled back with MainThread.BeginInvokeOnMainThread (or InvokeOnMainThreadAsync).
MainThread.BeginInvokeOnMainThread(() => statusLabel.Text = "Done");
Real-world example A background download updates a progress label only after marshaling back to the UI thread, avoiding a cross-thread crash.

Common follow-ups: How do you check if you're on the UI thread? | What runs off the UI thread?

Threading Performance & Optimization Concurrency & Threading
Offload CPU-bound work with Task.Run so it executes on a thread-pool thread, await the result, then update UI on the main thread. Don't use Task.Run for I/O (await the async API directly). Keep the UI responsive by never blocking it with .Result or .Wait().
var result = await Task.Run(() => ExpensiveCompute(data));
resultLabel.Text = result.ToString();   // back on UI thread after await
Real-world example Image processing runs on a background thread via Task.Run so the UI stays responsive, then shows the result.

Common follow-ups: Why not Task.Run for I/O? | Why avoid .Result?

Threading Async Concurrency & Threading
Avoid async void except for event handlers (it swallows exceptions); don't block with .Result/.Wait() (deadlocks/UI freeze); use ConfigureAwait appropriately in library code; and handle exceptions in fire-and-forget tasks. Prefer async Task and propagate cancellation with CancellationToken.
// Bad: async void hides exceptions
async void Load() { await FetchAsync(); }
// Better: async Task, awaited or safely handled
async Task LoadAsync() { await FetchAsync(); }
Real-world example A silent failure disappears once a fire-and-forget async void is converted to an awaited async Task with try/catch.

Common follow-ups: When is async void acceptable? | How do you cancel async work?

Async Testing & Debugging Concurrency & Threading
Pass a CancellationToken through async calls and trigger it with a CancellationTokenSource when the user navigates away or cancels. Check the token in loops and pass it to cancellation-aware APIs (HttpClient, delays). Dispose the source and handle OperationCanceledException.
_cts = new CancellationTokenSource();
try { await _api.SearchAsync(query, _cts.Token); }
catch (OperationCanceledException) { /* ignore */ }
// On new keystroke: _cts.Cancel();
Real-world example A type-ahead search cancels the in-flight request on each new keystroke so only the latest query completes.

Common follow-ups: Where do you check the token? | What exception signals cancellation?

Async Networking & APIs Concurrency & Threading
Marshal collection mutations to the UI thread, since CollectionView observes changes on the UI thread. Compute/fetch data in the background, then add items via MainThread.BeginInvokeOnMainThread, or gather results and assign once. Some toolkit collections offer thread-safe patterns, but explicit marshaling is safest.
var page = await _api.GetPageAsync();
MainThread.BeginInvokeOnMainThread(() =>
{
    foreach (var item in page) Items.Add(item);
});
Real-world example Paged results fetched off-thread are appended to the bound ObservableCollection on the UI thread to avoid exceptions.

Common follow-ups: Why marshal collection changes? | Can you assign the whole collection at once?

Threading Collections Concurrency & Threading