这是 this question 的后续内容。我还读过 Stephen Toub 的 "Tasks and Unhandled Exceptions"我想我理解任务和异常(exception)是如何工作的以及“观察到的任务”的含义。 但是,我无法弄清楚如何判断是否已观察到任务
。如果不使用反射,这是否可能?
我想借@Noseratio's code举个例子:
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);
}
最佳答案
任务不知道它们是否已被等待。这有点像询问一个整数是否知道它是否已被添加到另一个整数。
但是,任务的异常是可以被观察到的,并且异常是否被观察到实际上是被任务记住的。区分未观察到的异常和未等待的任务非常重要。运行时对于未观察到的任务异常有一些特殊的逻辑,但对于未等待的任务没有做任何特殊的事情。
您确实不应该编写依赖于是否已等待任务的代码。如果 DoSomething 的语义是即使结果被忽略(一个非常奇怪但技术上有效的要求)也应该始终等待它,那么此代码应该足够了:
var task = DoSomething();
try
{
bool ready = await DoSomethingElse();
if (!ready)
return null;
var value = await DoThirdThing(); // depends on DoSomethingElse
return value + await task;
}
finally
{
await task;
}
另一方面,如果 DoSomething
的语义是如果根本不需要结果(情况更可能如此),则可以忽略该任务,那么此代码应该足够了:
var task = DoSomething();
bool ready = await DoSomethingElse();
if (!ready)
return null;
var value = await DoThirdThing(); // depends on DoSomethingElse
return value + await task;
无需担心任务是否已等待。
关于c# - 如何判断 Task 是否为 "observed"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33446488/