[英]If an instance is not referenced but its callback is, will the instance be garbage collected?
[英]Will an instance be garbage collected if a Task's callback get reference to the instance itself?
public class Cls
{
public object Obj { get; set; }
public async void Func()
{
Task.Run(() =>
{
Thread.Sleep(999999999);
this.Obj = new { };
});
}
}
public class Program
{
public static void Main(string[] args)
{
new Cls().Func();
}
}
请考虑上面的代码,如果它首先有意义,请忽略它。 在上述情况下,我没有将Cls
的实例存储到任何变量中,似乎没有任何东西引用该实例,它将是 GC。 但是,在Func
侧有一个Task.Run()
。 Task
的回调 function 引用了实例的Obj
属性。 在这种情况下,我还能被 GC 收集吗?
我问这个问题是因为在 SignalR 的微软文档中它说
在调用依赖于集线器保持活动状态的异步方法时使用等待。
我不明白,只要Clients.All.SendAsync
中的某些内容引用Hub
本身, Hub
为什么不会仍然存在......
谢谢。
不,它不会被垃圾收集,因为您在Task.Run()
中引用了this
(即使您在调用Thead.Sleep()
之前引用this
)。
但是,如果您在 Azure 函数中运行此代码,例如,框架可能会终止您的应用程序实例,并且回调中的代码将永远不会运行(不是因为被垃圾收集)。
顺便说一句,您可以通过调用执行垃圾收集的GC.Collect()
手动检查它是否被垃圾收集。
您可以使用此代码对其进行测试(例如,在 C# Interactive 中运行它)
static async Task Main(string[] args)
{
static void CreateObjectAndCallFunc()
{
var clsInstance = new Cls();
clsInstance.Func();
}
CreateObjectAndCallFunc();
Console.WriteLine($"before Task.Delay");
await Task.Delay(10);
Console.WriteLine($"after Task.Delay");
Console.WriteLine($"GC.Collect()");
GC.Collect();
Console.WriteLine($"after GC.Collect()");
Console.WriteLine($"before Task.Delay");
await Task.Delay(10);
Console.WriteLine($"after Task.Delay");
}
public class Cls
{
public Cls() { Console.WriteLine("Cls constructor"); }
~Cls() { Console.WriteLine("!!! Cls deconstructor"); }
public object Obj { get; set; }
public void Func()
{
Task.Run(() =>
{
System.Threading.Thread.Sleep(99999);
this.Obj = new object();
});
}
}
await Main(null);
如果您在 Task.Run(..) 中没有引用this.Obj
,那么它将 output 这个:
Cls constructor
before Task.Delay
after Task.Delay
GC.Collect()
after GC.Collect()
before Task.Delay
!!! Cls deconstructor
after Task.Delay
但如果你这样做,它将 output 这个:
Cls constructor
before Task.Delay
after Task.Delay
GC.Collect()
after GC.Collect()
before Task.Delay
after Task.Delay
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.