Количество потоков в виде корневых объектов; Я не знаю точно, как работает BackgroundWorker, но кажется вероятным, что метод первичного потока будет иметь доступ к состоянию на рабочем экземпляре; как таковой, сам рабочий поток будет поддерживать экземпляр BackgroundWorker до тех пор, пока (по крайней мере) поток не выйдет.
Конечно; коллекция также требует, чтобы все другие (живые) объекты отменили ссылку на рабочий объект; обратите внимание также, что коллекция переменных стека может отличаться в отладке/выпуске и с/без отладчика.
[редактировать] Как также было отмечено; обработчики событий на рабочем месте (в вашем коде) будут сохранять живые объекты «просмотра» и «обновления» (через делегата), но не наоборот. До тех пор, пока у работника будет более короткая жизнь, чем «вид» и «обновление», вам не нужно получать параноик об отмене подписки на события. Я редактировал код для включения объекта «SomeTarget», на который ссылается только работник: вы должны увидеть этот эффект (т. Е. Цель умирает вместе с рабочим).
Re рабочий сбор собран, когда нить умирает: вот доказательство; Вы должны увидеть «работник доработан» после того, как работник сообщает выхода:
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
class Demo : Form
{
class ChattyWorker : BackgroundWorker
{
~ChattyWorker()
{
Console.WriteLine("Worker finalized");
}
}
class SomeTarget
{
~SomeTarget()
{
Console.WriteLine("Target finalized");
}
public SomeTarget()
{
Console.WriteLine("Target created");
}
public void Foo(object sender, EventArgs args)
{
Console.WriteLine("Foo");
}
}
static void Collect(object sender, EventArgs args)
{
Console.WriteLine("Collecting...");
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Interval = 100;
timer.Tick += Collect;
timer.Start();
ChattyWorker worker = new ChattyWorker();
worker.RunWorkerCompleted += new SomeTarget().Foo;
worker.DoWork += delegate
{
Console.WriteLine("Worker starting");
for (int i = 0; i < 10; i++)
{
Thread.Sleep(250);
Console.WriteLine(i);
}
Console.WriteLine("Worker exiting");
};
worker.RunWorkerAsync();
}
[STAThread]
static void Main()
{ // using a form to force a sync context
Application.Run(new Demo());
}
}
Откуда вы знаете, что они не собираются? – StingyJack 2008-10-28 15:14:35