c# - 是什么让委托(delegate)多目标对象留在范围内?

标签 c# .net delegates garbage-collection

是什么让 t 成为有根引用(留在范围内)? (t 是用户定义的类)

我在 IL spy 中查看,它不是一个常见的捕获变量!

Action runs = null;
while (dummy <= tod.Value.Date)
{
   var t = new Task(dummy, _interval);
   runs += t.Run;

   dummy = dummy.AddDays(1);
}
GC.Collect();
((Action)(() => { runs(); })).BeginInvoke(Result, null);

有人能给我解释一下吗? t(任务)类如何保持在范围内,是什么让它 Root ,我猜它是运行委托(delegate),但如何?

最佳答案

首先,我应该指出这与范围 没有太大关系,范围 是程序文本的区域,在该区域中可以使用实体的简单名称来引用实体。这是关于可达性

现在我还没有用内存分析器查看有问题的堆,但是 Task 对象的路径看起来像这样:

  1. Action(多播)委托(delegate)实例是 GC 根,因为它被 runs(本地)引用。
  2. 此委托(delegate)实例又通过其 _invocationlist 字段保持其各个订阅者处于事件状态,该字段包含对委托(delegate)数组的引用。
  3. 此数组又包含对单个(单播)Action 委托(delegate)实例的引用。
  4. 这些单独的委托(delegate)中的每一个都将是一个封闭实例委托(delegate),具有填充的_target字段(它将充当传递的this引用到调用委托(delegate)时的 Task.Run 方法)。该字段将保存对 Task 实例的引用。

总结:

    runs local
-> Multicast Action object
-> (through _invocationlist field) Array of references to Action objects
-> (through a specific array element) Unicast Action object
-> (through _target field) Task object

更新:

我通过 Ants Memory Profiler 运行了这个,这证实了我的想法:

Path to Task object

关于c# - 是什么让委托(delegate)多目标对象留在范围内?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8646573/

相关文章:

c# - 如何识别右键单击 ContextMenuStrip 的 dataGridView 单元格?

c# - .net 处理表单中的图像资源

c# - Panel.Dock Fill 忽略其他 Panel.Dock 设置

c# - BeginInvoke 抛出异常

c# - ASP.NET MVC 3 - 创建仅用于返回的动态对象

c# - 运算符 '!=' 不能应用于类型 'bool?' 和 'int' 的操作数

ios - 数据从 watch 发送到手机后未调用 Swift 3 XML 解析委托(delegate)

c# - 用于处理任何事件的通用委托(delegate)类型

c# - JsonConvert.DeserializeObject 在一个项目中工作,但在另一个项目中不起作用

c# - "Could not find type"在 Windows 窗体设计器中加载窗体时出错