Фоновый работник и сбор мусора? - программирование
Подтвердить что ты не робот

Фоновый работник и сбор мусора?

Могу ли я определить фонового работника в методе?

private void DownLoadFile(string fileLocation){
  BackgroundWorker worker = new BackgroundWorker();

  worker.DoWork += new DoWorkEventHandler((obj, args) => { 
      // Will be executed by back ground thread asynchronously.
      args.Result = Download(fileLocation);   
  });

  worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler((obj, args) => { 
      // will be executed in the main thread.
      Result r = args.Result as Result;
      ReportResult(r);
   });

   worker.RunWorkerAsync(fileLocation);
}

Вопрос. Если функция Download() занимает много времени, чтобы загрузить файл, может ли GC ударить и собрать рабочий объект до выполнения RunWorkerCompleted()?

4b9b3361

Ответ 1

Учитывая, что вы фактически не используете большую часть функций BackgroundWorker, я бы рекомендовал вместо этого использовать TPL:

private void DownLoadFile(string fileLocation)
{
    Task.Factory.StartNew( () => Download(fileLocation))
        .ContinueWith(t => ReportResult(t.Result), TaskScheduler.FromCurrentSynchronizationContext());
}

При этом объект worker не будет собирать мусор после его запуска, так как поток ThreadPool сам будет содержать рабочего как "использованный объект". Сборщик мусора не сможет его собирать до тех пор, пока не исполнится обработчик события завершения, и в этот момент не будет кода пользователя, который мог бы достигнуть экземпляра BackgroundWorker.

Кроме того, скорее всего, экземпляр этого класса не будет собран из мусора, поскольку методы экземпляра (ReportResults), используемые закрытием, сохраняют экземпляр "this" доступным и не пригодным для GC.