I'd like to do something like this:
public async Task<int> DoWork(int parameter) {
try {
await OperationThatMayCompleteSynchronously(parameter);
} catch(Exception) e {
if(completedSynchronously)
doSyncThing();
else
doAsyncThing();
}
}
Note: I'm running tasks on the thread pool, so there is no async context.
I'd like to be able to tell the difference between an exception thrown immediately, and I'm still on the calling thread (e.g. parameter
is invalid causing the function to abort), and an exception thrown when the async task completes, and I'm on some other random callback thread (e.g. network failure)
I can work out how I might achieve this if I didn't use await
, and just used ContinueWith
on the async operation, but is it possible using await
?
The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active.
Async never schedules your method to run on a background thread. The only way to do that is using something like Task. Run , which is explicitly for that purpose. In the case of a UI application, that means the code before the first await runs in the UI thread.
Because await is only valid inside async functions and modules, which themselves are asynchronous and return promises, the await expression never blocks the main thread and only defers execution of code that actually depends on the result, i.e. anything after the await expression.
We know now that await doesn't block - it frees up the calling thread.
Store the task in a variable:
var task = OperationThatMayCompleteSynchronously(parameter); //may throw
Then await it:
await task; //may throw
That way you can differentiate between the two origins for a potential exception.
Note, that async
methods never throw directly. They pass exceptions through the task they return. This is true even for "validation" throws that execute before the first await.
Instead of awaiting, you can call Wait()
or Result
, since you claim that there's no synchronization context, and, if the exception caught is AggregateException
, it was not thrown in the calling thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With