如何判断任务是否已"被观察"?

avo*_*avo 2 .net c# exception task-parallel-library async-await

这是这个问题的后续行动.我还读过Stephen Toub的"任务和未处理的异常",我想我理解任务和异常是如何工作的以及"观察任务"的含义.然而,我无法弄清楚如何判断是否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);
 }
Run Code Online (Sandbox Code Playgroud)

如果我们可以判断是否已经观察到任务,那么这可以更简单,更易读:

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);
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*ary 5

任务不知道他们是否已被等待.这有点像询问整数是否知道它是否已被添加到另一个整数.

但是,可以观察到任务的异常,并且是否已经观察到异常实际上是由任务记住的.区分未观察到的异常未完成的任务非常重要.对于未观察到的任务异常,运行时具有一些特殊逻辑,但对于未单独执行的任务不会执行任何特殊操作.

你真的不应该编写依赖于是否等待任务的代码.如果语义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;
}
Run Code Online (Sandbox Code Playgroud)

另一方面,如果语义DoSomething是可以忽略任务,如果根本不需要结果(这种情况的可能性更大),那么这段代码应该足够了:

var task = DoSomething();
bool ready = await DoSomethingElse();
if (!ready) 
  return null;

var value = await DoThirdThing(); // depends on DoSomethingElse
return value + await task;
Run Code Online (Sandbox Code Playgroud)

无需担心是否已经等待任务.