#c# #.net #multithreading #garbage-collection #threadpool
#c# #.net #многопоточность #сбор мусора #threadpool
Вопрос:
Учитывая следующее…
public MyClass
{
public void MyClass()
{
var myWorkerClass = new MyWorkerClass();
myWorkerClass.DoSomething();
// and exit quickly
}
}
public MyWorkerClass()
{
public void DoSomething()
{
ThreadPool.QueueUserWorkItem(() =>
{
SomeLongRunningProcess();
});
}
public static void SomeLongRunningProcess()
{
// Something that takes a long time
}
}
Когда MyWorkerClass и MyClass получат право на сборку мусора?
Я думаю об анонимной функции в MyWorkClass.doSomething() будет сохранен в пространстве объявления локальной переменной MyWorkerClass. Этого будет достаточно для ссылки, чтобы сохранить их до завершения потока. Правильно ли это?
Комментарии:
1. Нужно ли его хранить? Метод, который ставится в очередь, является статическим, поэтому неявно не требует какой-либо ссылки на
MyWorkerClass
экземпляр.2. Примечание: как правило, не рекомендуется ставить в очередь длительно выполняющиеся задания в пуле потоков, поскольку это заставляет пул создавать дополнительные потоки.
Ответ №1:
MyClass должен иметь право на сбор немедленно. MyWorkerClass получит право на сбор после завершения SomeLongRunningProcess() (при условии, что упомянутый метод ссылается на «this», чего нет в вашем примере).
В том виде, в каком ваш код существует сейчас, оба экземпляра немедленно допускаются.
Если вы хотите, чтобы MyClass или MyWorkerClass зависали, ссылайтесь на него из SomeLongRunningProcess или закрытия, которое его вызывает.
Комментарии:
1.
SomeLongRunningProgress
не имеет athis
, потому что это статический метод. Если вы хотитеMyClass
илиMyWorkerClass
зависнуть, используйтеGC.KeepAlive
. Вот для чего это нужно.