Что такое жизненный цикл задачи?когда это закончится или соберется в C #? - PullRequest
0 голосов
/ 21 мая 2018

Я довольно новичок в TPL и хотел бы получить ответ на вопрос: что такое жизненный цикл задачи?когда это закончится или соберется в C #?Если задача создана для однократного использования - она ​​выполняет одноразовую работу и затем завершается - нужно ли ее отменить?сборщик мусора собирает его?

Вот пример:

    DoSomething()
   {
      Task task = Task.Factory.StartNew(()=>DoOneTimeWork());
   }

Кто-нибудь может подсказать, что случилось с локальной задачей после завершения DoOneTimeWork?

Большое спасибо!

1 Ответ

0 голосов
/ 22 мая 2018

Поскольку вы спрашивали о GC, я отвечу, но, как я говорю, я не думаю, что это особенно интересно, и я бы больше беспокоился о любых ненаблюдаемых исключениях, вызванных вашим кодом, так как вы не предоставляете ссылку назадайте себе задачу и не ставьте в очередь дальнейшие взаимодействия с ним через ContinueWith.

В тот момент, когда возвращается Task.Factory.StartNew (хотя обычно предпочитается Task.Run в наши дни), система времени выполнения создаст задачу ибудет поддерживать сильную ссылку на эту задачу.До тех пор, пока DoOneTimeWork не завершит, нормально или ненормально, эта ссылка, по крайней мере, будет препятствовать сбору объекта Task.

После завершения DoOneTimeWork, Task будет обновляться для записи егосостояние завершения и время выполнения больше не будут поддерживать ссылку.Поскольку DoSomething никогда не читает из task, и (как указано выше) никакие другие ссылки на Task не представляются возможными, то даже если DoSomething все еще работает, Task теперь будет иметь право насбор, в какой-то будущий момент времени 1 .

Когда этот сбор произойдет, конечно, неизвестно детерминистически.Насколько нам известно, ваш код выполняется в пользовательском CLR с Zero Garbage Collector , и поэтому фактически никогда не может быть собран.

нужно ли его отменить?

Нет, отмена в TPL кооператив .Он включает в себя использование CancellationToken s, и после запроса отмены код, выполняющий в пределах , Task должен иметь доступ к токену отмены и реализовать некоторую логику, чтобы вызвать отмену.

Если конкретный Task уже завершил , то он не может запускать какой-либо дополнительный код, и поэтому даже если ваш код использовал CancellationToken и запрашивал отмену, он выигралне отменено и не должно быть.


1 Это примерно то же самое для любого другого управляемого объекта во время выполнения - после всех сильных ссылок наобъект больше не доступен из корней GC, после чего объект будет иметь право на сбор 2 .Вот почему я сказал, что не думаю, что это особенно интересно.

2 Или финализация и коллекция для объектов с финализаторами, со всеми обычными предостережениями вокруг этого.

...