C# 没有引用的正在运行的异步类实例是否会被垃圾收集?

C# 没有引用的正在运行的异步类实例是否会被垃圾收集?,c#,.net,C#,.net,如果我在一个无名实例上调用一个async函数,该实例会一直保持活动状态直到函数完成吗?例如,如果我有一台需要在后台运行一段时间的服务器。我对该服务器的状态或以任何方式跟踪它都不感兴趣。我可以这样做: ... new MyServer().Start(); ... class MyServer { ... async Task Start() { ... } ... } Start方法是否会一直运行到完成,或者无名的无引用实例是否会在完成运行之前成为GC?在幕后仍然有一个引用。异步方

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

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

Start
方法是否会一直运行到完成,或者无名的无引用实例是否会在完成运行之前成为GC?

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


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

在类似情况下,我使用a(如图所示,以防止收集委托)或
SafeHandle
派生类对象。如果在
async
函数中我使用
.ConfigureAwait(false)是否有区别
?ConfigureAwait(false)只是让它始终使用默认线程池上下文,而不是其中设置的任何上下文。从另一个角度来看,每个
await
都相当于
.GetAwaiter().OnCompleted(MoveNext)
。对状态机
MoveNext
的引用将使任务保持活动状态,直到运行时/OS可以恢复任务。