【问题标题】:Does a running async class instance without a reference get garbage collected?没有引用的正在运行的异步类实例是否会被垃圾收集?
【发布时间】:2020-05-18 17:37:42
【问题描述】:

如果我在一个无名实例上调用async 函数,该实例会在函数完成之前保持活动状态吗?例如,如果我有一个需要在后台运行一段时间的服务器。我对此服务器的状态或以任何方式跟踪它不感兴趣。我可能会这样做:

...
new MyServer().Start();
...
class MyServer {
  ...
  async Task Start() { ... }
  ...
}

Start 方法会一直运行到完成,还是无名无引用实例在完成运行之前会被 GC?

【问题讨论】:

  • 我使用GCHandle(例如here,以防止委托被收集)或SafeHandle派生类对象,类似场合。

标签: c# .net


【解决方案1】:

幕后仍有参考。异步方法的延续通过其Post 方法注册到SynchronizationContext.Current 下设置的SynchronizationContext (如果.Current 为null,则为线程池)。这种延续将使引用保持活动状态。

有一点需要注意,以上只是在讨论垃圾收集器收集你的类。如果您在 IIS 中运行,您的应用程序域可能会在您的任务完成之前关闭,这将终止服务器。如果这是您的情况,您应该使用IHostedService 来保持您的服务正常运行。

【讨论】:

  • 如果在async 函数中我使用.ConfigureAwait(false) 会有什么不同吗?
  • ConfigureAwait(false) 只是让它始终使用默认线程池上下文而不是 .Current 中设置的任何内容
  • 另一种思考方式,每个await 都是等同于.GetAwaiter().OnCompleted(MoveNext) 的语法糖。对您的状态机 MoveNext 的引用将使您的任务保持活动状态,直到运行时/操作系统可以恢复您的任务。
猜你喜欢
  • 2016-02-04
  • 1970-01-01
  • 2020-02-11
  • 2020-05-11
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多