English
Summary
Conclusions
The Windows Forms UI thread processes all messages one at a time, so a long synchronous operation in a handler "freezes" the window. Task and Task<T> represent operations that will complete later, and the await operator releases the thread while waiting and, thanks to the synchronization context, returns the continuation to the UI thread. I/O operations are called through their …Async methods, and computations are moved to the thread pool with Task.Run. IProgress<T> safely passes progress to the form, CancellationTokenSource and CancellationToken implement cooperative cancellation and timeouts, IAsyncEnumerable<T> yields results gradually, and Task.WhenAll, WhenAny, WhenEach, and SemaphoreSlim manage several tasks. A task's result is obtained only through await, async void is used only for event handlers, and in .NET 10 the asynchronous InvokeAsync, ShowDialogAsync, and TaskDialog.ShowDialogAsync methods are available without any configuration.
Self-check questions
- Why does a long-running event handler make a Windows Forms window "Not Responding"?
- How do I/O operations differ from computations? How do you run each of them in a GUI application?
- What is a
Task? What states can it have? - Why are
task.Resultandtask.Wait()not used on the UI thread? - What happens when the
awaitoperator is applied to an incomplete task? - Which types can an
asyncmethod return? When isasync voidacceptable? - What does CS4014 warn about?
- What is a synchronization context? How does the behavior of
awaitdiffer in a console program and in a Windows Forms application? - When does the "Cross-thread operation not valid" exception occur, and how do you avoid it?
- How does a deadlock occur because of
Result? What isConfigureAwait(false)for? - How do
IProgress<T>andProgress<T>work? On which thread does theProgress<T>handler run? - How do you implement canceling an operation with a button and a timeout?
- What are the asynchronous streams
IAsyncEnumerable<T>and theawait foreachloop for? - How do
Task.WhenAll,Task.WhenAny, andTask.WhenEachdiffer? How do you limit the number of concurrent operations? - How are exceptions from
awaitandTask.WhenAllcaught? What happens to an exception inasync void? - What are
Control.InvokeAsyncandForm.ShowDialogAsyncfor? Is suppressing WFO5002 needed in .NET 10?
Useful links
- Asynchronous programming in C#: https://learn.microsoft.com/dotnet/csharp/asynchronous-programming/
- The Task-based Asynchronous Pattern (TAP): https://learn.microsoft.com/dotnet/standard/asynchronous-programming-patterns/task-based-asynchronous-pattern-tap
- Async return types: https://learn.microsoft.com/dotnet/csharp/asynchronous-programming/async-return-types
- Cancellation in managed threads: https://learn.microsoft.com/dotnet/standard/threading/cancellation-in-managed-threads
- Asynchronous streams: https://learn.microsoft.com/dotnet/csharp/asynchronous-programming/generate-consume-asynchronous-stream
- Making thread-safe calls to controls: https://learn.microsoft.com/dotnet/desktop/winforms/controls/how-to-make-thread-safe-calls
- What's new in Windows Forms for .NET 9: https://learn.microsoft.com/dotnet/desktop/winforms/whats-new/net90
- Error WFO5002: https://learn.microsoft.com/dotnet/desktop/winforms/compiler-messages/wfo5002
- The Tasks window: https://learn.microsoft.com/visualstudio/debugger/using-the-tasks-window