Сборка мусора с помощью ThreadPool

#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 не имеет a this , потому что это статический метод. Если вы хотите MyClass или MyWorkerClass зависнуть, используйте GC.KeepAlive . Вот для чего это нужно.