Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

async await exception catching - which thread am I on?

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?

like image 968
Orion Edwards Avatar asked Jul 08 '15 22:07

Orion Edwards


People also ask

Is async await on the same thread?

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.

Does async run on different thread?

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.

Does await stop the main 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.

Does await free the thread?

We know now that await doesn't block - it frees up the calling thread.


2 Answers

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.

like image 154
usr Avatar answered Sep 22 '22 12:09

usr


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.

like image 35
Paulo Morgado Avatar answered Sep 26 '22 12:09

Paulo Morgado