Почему бы не заключить в оператор использования? Не так много дополнительных усилий, и вы получите распоряжение:
private void PerformLongRunningOperation()
{
using (BackgroundWorker worker = new BackgroundWorker())
{
worker.DoWork += delegate
{
// perform long running operation here
};
worker.RunWorkerAsync();
}
}
EDIT:
Хорошо, я собрал небольшой тест, чтобы увидеть, что происходит с утилизацией и еще много чего:
using System;
using System.ComponentModel;
using System.Threading;
namespace BackgroundWorkerTest
{
internal class Program
{
private static BackgroundWorker _privateWorker;
private static void Main()
{
PrintThread("Main");
_privateWorker = new BackgroundWorker();
_privateWorker.DoWork += WorkerDoWork;
_privateWorker.RunWorkerCompleted += WorkerRunWorkerCompleted;
_privateWorker.Disposed += WorkerDisposed;
_privateWorker.RunWorkerAsync();
_privateWorker.Dispose();
_privateWorker = null;
using (var BW = new BackgroundWorker())
{
BW.DoWork += delegate
{
Thread.Sleep(2000);
PrintThread("Using Worker Working");
};
BW.Disposed += delegate { PrintThread("Using Worker Disposed"); };
BW.RunWorkerCompleted += delegate { PrintThread("Using Worker Completed"); };
BW.RunWorkerAsync();
}
Console.ReadLine();
}
private static void WorkerDisposed(object sender, EventArgs e)
{
PrintThread("Private Worker Disposed");
}
private static void WorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
PrintThread("Private Worker Completed");
}
private static void WorkerDoWork(object sender, DoWorkEventArgs e)
{
Thread.Sleep(2000);
PrintThread("Private Worker Working");
}
private static void PrintThread(string caller)
{
Console.WriteLine("{0} Thread: {1}", caller, Thread.CurrentThread.ManagedThreadId);
}
}
}
Вот вывод:
Main Thread: 1
Private Worker Disposed Thread: 1
Using Worker Disposed Thread: 1
Private Worker Working Thread: 3
Using Worker Working Thread: 4
Using Worker Completed Thread: 4
Private Worker Completed Thread: 3
Из некоторых тестов выясняется, что Dispose () практически не влияет на инициированный BackgroundWorker. Независимо от того, вызываете ли вы его в области действия оператора using или используете его, объявленный в коде, и сразу же удаляете его и разыменовываете, оно все равно работает нормально. Событие Disposed происходит в главном потоке, а DoWork и RunWorkerCompleted происходят в потоках пула потоков (в зависимости от того, какой из них доступен при возникновении события). Я пробовал случай, когда я незарегистрировал событие RunWorkerCompleted сразу после того, как вызвал Dispose (так, прежде чем у DoWork была возможность завершиться), а RunWorkerCompleted не сработал. Это наводит меня на мысль, что вы все еще можете манипулировать объектом BackgroundWorker, несмотря на его удаление.
Итак, как уже упоминали другие, в настоящее время кажется, что вызов Dispose на самом деле не требуется. Тем не менее, я не вижу никакого вреда в этом, по крайней мере, из моего опыта и этих тестов.