如何判断任务已经"观察"? [英] How to tell if Task has been "observed"?

查看:122
本文介绍了如何判断任务已经"观察"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个后续这个问题。我也看到了斯蒂芬Toub的任务和未处理的异常 我想我知道如何工作和异常工作,什么观测任务的意思。 然而,我无法弄清楚如何判断一个工作已发现还是不行。是在所有可能的,而无需使用反射?

我想借用 @ Noseratio的code 为例:

 静态异步无效观察(工作任务)
{
    等待任务;
}

// ...

VAR taskObserved = FALSE;
VAR任务= DoSomething的()
尝试
{
    布尔准备=等待DoSomethingElse();
    如果(!准备好)
      返回null;

    VAR值=等待DoThirdThing(); //取决于DoSomethingElse
    taskObserved = TRUE;
    返回值+等待任务;
 }
 最后
 {
     如果(!taskObserved)
        观察(任务);
 }
 

如果我们能告诉的任务是否已得到遵守,这可以变得更简单,更可读的:

 静态异步无效观察(工作任务)
{
    如果(!task.WasObserved)
        等待任务;
}

// ...

VAR任务= DoSomething的()
尝试
{
    布尔准备=等待DoSomethingElse();
    如果(!准备好)
      返回null;

    VAR值=等待DoThirdThing(); //取决于DoSomethingElse
    返回值+等待任务;
}
最后
{
    观察(任务);
}
 

解决方案

任务不知道他们是否已经期待与否。这有点像问如果一个整数知道,如果它被添加到另一个整数与否。

然而,该任务的的例外的可观察到的,和该异常已观察是否实际上由任务记住。这是很重要的未观察到的异常 unawaited任务的区分。运行时有未观测到的任务异常一些特殊的逻辑,但并没有做什么特别的unawaited任务。

您真的不应该写code这取决于任务是否已经期待已久。如果的DoSomething 的语义是,即使结果被忽略,它总是要等待(一个非常奇怪的 - 但技术上有效 - 要求),那么这个code必须足够了:

  VAR任务= DoSomething的();
尝试
{
  布尔准备=等待DoSomethingElse();
  如果(!准备好)
    返回null;

  VAR值=等待DoThirdThing(); //取决于DoSomethingElse
  返回值+等待任务;
}
最后
{
  等待任务;
}
 

在另一方面,如果 DoSomething的的语义是该任务可以如果结果是毕竟不需要(这是更可能的情况下被忽略),那么这个code应该足够了:

  VAR任务= DoSomething的();
布尔准备=等待DoSomethingElse();
如果(!准备好)
  返回null;

VAR值=等待DoThirdThing(); //取决于DoSomethingElse
返回值+等待任务;
 

没有必要更动担心任务是否已经期待已久的。

This is a follow-up to this question. I've also read Stephen Toub's "Tasks and Unhandled Exceptions" and I think I understand how tasks and exceptions work and what "observed task" means. I however cannot figure out how to tell if a Task has been observed or not. Is that possible at all without using reflection?

I'd like to borrow @Noseratio's code as an example:

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);
 }

If we could tell whether the task had been observed, this could be made simpler and more readable:

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);
}

解决方案

Tasks have no idea whether they've been awaited or not. It's kind of like asking if an integer knows if it's been added to another integer or not.

However, the task's exception can be observed, and whether the exception has been observed is in fact remembered by the task. It's important to distinguish between unobserved exceptions and unawaited tasks. The runtime has some special logic for unobserved task exceptions, but does not do anything special for unawaited tasks.

You really should not write code that depends on whether a task has been awaited. If the semantics for DoSomething are that it always should be awaited even if the result is ignored (a very odd - but technically valid - requirement), then this code should suffice:

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;
}

On the other hand, if the semantics of DoSomething are that the task can be ignored if the result isn't needed after all (which is far more likely the case), then this code should suffice:

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

var value = await DoThirdThing(); // depends on DoSomethingElse
return value + await task;

No need to mess around with worrying about whether a task has been awaited.

这篇关于如何判断任务已经"观察"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆