由于垃圾回收,对Task.GetAwaiter().OnCompleted()的调用是否会失败

本文关键字:OnCompleted 是否 失败 调用 GetAwaiter 于垃圾 Task | 更新日期: 2023-09-27 17:50:15

示例:

var task = Task.Factory.StartNew(() =>
{
  Thread.Sleep(1000);
  throw new Exception("fault!");
});
task.GetAwaiter().OnCompleted(() =>
{
  if (task.IsFaulted)
  {
    Console.WriteLine(task.Exception);
  }
});

上面的代码使用TaskAwaiter等待任务完成。我在web上的几个示例中看到过这样的代码,无论是使用OnCompleted还是使用GetResult

是否有必要明确地保留对awaiter的引用,以便回调工作?换句话说,如果在任务终止之前对awaiter进行了垃圾收集,这是一个问题吗?

由于垃圾回收,对Task.GetAwaiter().OnCompleted()的调用是否会失败

是否有必要明确地保留对awaiter的引用,以便回调工作?换句话说,如果在任务终止之前对awaiter进行了垃圾收集,这是一个问题吗?

我不知道怎么会这样。唯一可能成为问题的方法是,如果需要使用awaiter对象。但要想做到这一点,它必须引用awaiter对象。但是,如果它引用了awaiter对象,那么该对象就不会被垃圾回收。

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

你为什么打GetAwaiter()?听起来,在你的问题中提供更多的细节可能会让你受益,这样就可以提供一个满足你更广泛需求的答案(或者你可以只问第二个问题来征求建议(。

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

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