Consuming Task based methods
Treat warnings as errors
Fixing our code
async and awaitvoid can stay void -> we call this fire and forgetvoid can become Task -> our caller can await usReturnType becomes Task<ReturnType>Always check cancellation!
async is infectious - convert all callers and their callers until the roottry-catch in the void rootAlso known as details
IAsyncEnumerableSimple async patterns
The end is in the callback
Begin/End pair of methodsIsCompletedThis doesn't work!
Also doesn't work!
Events!
New async pattern
Switching from EAP to TPL
Tasks are a consistent interface
It is easy to chain them
Promises are tasks
OperationCancelledExceptionTask?Task represents an ongoing operation (but it may already be when you get it)CancellationToken - cooperative cancellationIProgress<T> - manual work, but still...Wrapper manages C# constructs
Simple sync code
Hmmmm
Assuming happy flow
That was easy!
async function is a state machine, but better than hand-written onevoid, Task or Task<T>unsafe, lock and constructorsConfigureAwait(false)
awaitsaves current thread by default!
ConfigureAwait(false) tells the app to not remember the threadWhy all participants need to use it
void root handlers should always catch!TaskScheduler.UnobservedTaskException will be invoked which won't crash your app since .NET 4.5 (but you can change it)Task immediately throws the inner exception.Task.RunRun heavy code...
Task.WhenAll and Task.WhenAnyGeneric extension method on all tasks!
async operation to finish synchronously by calling .Result, .Wait() or preferably .GetAwaiter().GetResult().| sync | async | |||
|---|---|---|---|---|
| one | T | Task<T> | ||
| many | IEnumerable<T> | IObservable<T> |
Task gives one result IObservable gives manyMotivating example - throttling async operations
Complicated, but can be made as a higher order operation
for and await are opaque -> they become Task<TResult>for-awaitHow to do SelectAsync
Truly async enumerables