C# 异步等待异常捕获-我在哪个线程上?

C# 异步等待异常捕获-我在哪个线程上?,c#,exception-handling,async-await,C#,Exception Handling,Async Await,我想这样做: public async Task<int> DoWork(int parameter) { try { await OperationThatMayCompleteSynchronously(parameter); } catch(Exception) e { if(completedSynchronously) doSyncThing(); else doA

我想这样做:

public async Task<int> DoWork(int parameter) {
    try {
        await OperationThatMayCompleteSynchronously(parameter);
    } catch(Exception) e { 
        if(completedSynchronously)
           doSyncThing();
        else
           doAsyncThing();
    }
}
公共异步任务DoWork(int参数){
试一试{
等待可能同步完成的操作(参数);
}捕获(例外)e{
如果(同步完成)
dosyncting();
其他的
doAsyncThing();
}
}
注意:我在线程池上运行任务,因此没有异步上下文

我希望能够区分立即抛出的异常和我仍在调用线程上的异常(例如,
参数
无效导致函数中止),以及异步任务完成时抛出的异常和我在其他随机回调线程上的异常(例如,网络故障)


如果我没有使用
await
,只是在异步操作中使用
ContinueWith
,我可以计算出如何实现这一点,但是否可以使用
await

将任务存储在变量中:

var task = OperationThatMayCompleteSynchronously(parameter); //may throw
然后等待它:

await task; //may throw
这样,您就可以区分潜在异常的两个来源


注意,
async
方法从不直接抛出。它们通过返回的任务传递异常。即使是在第一次等待之前执行的“验证”抛出也是如此。

您可以调用
Wait()
Result
,而不是等待,因为您声明没有同步上下文,并且,如果捕获到异常,它没有在调用线程中抛出。

请记住,如果可以同步完成的
操作是异步方法,则所有异常都将存储在任务中,并且不会抛出异常synchronously@OrionEdwards,以获得您想要的100%行为,您需要修改上面的内容以添加如下内容:
var task=operationthatthatthecompletetesynchronous(参数);如果(task.IsFaulted)task.GetAwaiter().GetResult()。你能解释一下这能完成什么吗?似乎等待就是这么做的。首先,如果
操作可能从其同步部分同步抛出,而不是在
等待
行,OP希望第一行立即抛出。如果此方法是
async
,例如
异步任务操作,可以同步完成(){throw new Exception();}
,则不会发生这种情况。它仍将在<代码>等待< /COD> >行,@ Ur.@ UR:考虑修改您的答案,也更新<代码>操作,可以同步完成 >,从而在非异步方法中执行同步异常。否则,你的第一行就永远不会抛出。我认为这比使用
IsFaulted
/
IsCompleted
@usr:Agree-re-thread-identity作为转移注意力的工具更干净。我只想明确地指出“包装器方法”,因为有时人们确实会假设
throw
before
await
将被直接抛出,而不是放在任务上。事实上,第一个异步CTP确实有这种行为。