对 Task.GetAwaiter().OnCompleted() 的调用是否会因为垃圾收集而失败?

Can a call to Task.GetAwaiter().OnCompleted() fail because of garbage collection?

示例:

var task = Task.Factory.StartNew(() =>
{
  Thread.Sleep(1000);
  throw new Exception("fault!");
});

task.GetAwaiter().OnCompleted(() =>
{
  if (task.IsFaulted)
  {
    Console.WriteLine(task.Exception);
  }
});

上面的代码使用 TaskAwaiter 等待任务完成。我在整个网络的几个示例中看到过这样的代码,使用 OnCompletedGetResult.

是否有必要明确保留对等待者的引用,以便回调正常工作?换句话说,如果等待者在任务终止之前被垃圾收集,是否有问题?

Is it necessary to keep a reference to the awaiter explicitly in order for the callback to work? In other words, is it a problem if the awaiter is garbage collected before the task terminates?

我不明白怎么可能。唯一可能成为问题的方法是是否需要使用 awaiter 对象。但要尝试这样做,它必须有一个对等待者对象的引用。但是如果它引用了 awaiter 对象,则该对象不会被垃圾回收。

也就是说,您为什么要以这种方式实现延续?通常,您只需使用 await 并在 await 调用之后在同一方法中编写延续。即使在由于某种原因它不起作用的情况下(例如不在 async 方法中),您通常也会使用 ContinueWith() 方法。

你为什么打电话给 GetAwaiter()?听起来您可能会受益于在您的问题中提供更多细节,以便可以提供满足您更广泛需求的答案(或者您可以提出第二个问题以征求相关建议)。

简而言之,在欣赏了所有答案和评论之后,我对使用 GetAwaiter() 的认识是:不要这样做

如果您需要它,这很可能表明您的异步设计急需重构。