这是对这个问题的跟进。我也阅读了Stephen Toub的“Tasks and Unhandled Exceptions”,我认为我理解了任务和异常的工作原理以及“observed task”的含义。然而,我无法弄清楚如何判断一个
如果我们可以知道任务是否被观察到,那么这个过程就可以变得更简单和易于阅读:
Task
是否已被观察到。是否有可能在不使用反射的情况下实现?
我想借鉴@Noseratio的代码作为示例:
static async void Observe(Task task)
{
await task;
}
// ...
var taskObserved = false;
var task = DoSomething()
try
{
bool ready = await DoSomethingElse();
if (!ready)
return null;
var value = await DoThirdThing(); // depends on DoSomethingElse
taskObserved = true;
return value + await task;
}
finally
{
if (!taskObserved)
Observe(task);
}
如果我们可以知道任务是否被观察到,那么这个过程就可以变得更简单和易于阅读:
static async void Observe(Task task)
{
if (!task.WasObserved)
await task;
}
// ...
var task = DoSomething()
try
{
bool ready = await DoSomethingElse();
if (!ready)
return null;
var value = await DoThirdThing(); // depends on DoSomethingElse
return value + await task;
}
finally
{
Observe(task);
}
Task.Exception
已被触发等。但是,我对您的第一个代码片段有一个问题,它不会抛出相同的异常两次吗?所以我会失去第一次抛出的堆栈帧吗? - avotask
以故障状态完成,则不会丢失堆栈帧。堆栈已经被捕获并放置在task.Exception
中的Exception
对象上。await
足够聪明,可以两次保留捕获的堆栈。 - Stephen ClearyDoSomethingElse
或DoThirdThing
抛出异常,我仍然希望能够传播这些异常,以便与DoSomething
一起抛出。但是,在这种情况下,DoSomething
接管了这些异常。 - avo