Что заставляет делегировать многоцелевой объект оставаться в области видимости? - PullRequest
3 голосов
/ 27 декабря 2011

Что делает 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 (задачи) остаются в области видимости, что делает их рутированными, я думаю, это делегат run, но как?

1 Ответ

6 голосов
/ 27 декабря 2011

Во-первых, я должен отметить, что это не имеет ничего общего с scope , который является областью текста программы, в которой можно ссылаться на сущность, используя ее простое имя.Речь идет о достижимости .

Теперь я не смотрел на эту кучу с помощью профилировщика памяти , но путь к Task объекту выглядел бы как-тонапример:

  1. Экземпляр делегата Action (многоадресная передача) является корнем GC, так как на него ссылается runs (локальный).
  2. Этот экземпляр делегата, в свою очередь, поддерживает работу отдельных подписчиков через поле _invocationlist, которое содержит ссылку на массив делегатов.
  3. Этот массив, в свою очередь, содержит ссылки на отдельного человека (одноадресная передача).Action экземпляры делегатов.
  4. Каждый из этих отдельных делегатов будет делегатом с закрытым экземпляром с заполненным полем _target (которое будет действовать как ссылка this, передаваемая методу 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

...