스레드 수는 루트 개체로 계산됩니다. BackgroundWorker가 어떻게 작동하는지 정확히 알지 못하지만 기본 스레드 메서드가 worker 인스턴스의 상태에 액세스 할 가능성이 높습니다. 따라서 작업 스레드 자체는 적어도 스레드가 종료 될 때까지 BackgroundWorker 인스턴스를 활성 상태로 유지합니다.
물론입니다. 컬렉션은 또한 다른 모든 (실제) 객체가 작업자 객체를 참조 해제해야한다고 요구합니다. 스택 변수의 콜렉션은 디버그/릴리즈에서 다를 수 있으며 디버거가 첨부되어 있거나 없을 수도 있습니다.
[편집] 또한 언급했듯이; (코드에서) 작업자의 이벤트 핸들러는 대리자를 통해 "보기"및 "업데이트"개체를 유지하지만 그 반대의 경우는 유지하지 않습니다. 근로자가 "보기"및 "업데이트"보다 수명이 짧으면 이벤트 구독을 취소하는 것에 대해 편집증을받을 필요가 없습니다. 작업자가 유일하게 참조하는 "SomeTarget"개체를 포함하도록 코드를 편집했습니다.이 효과 (예 : 대상이 작업자와 함께 사망 함)가 표시되어야합니다.
스레드가 죽으면 다시 작업자가 수집됩니다. 여기에 증거가 있습니다. 작업자가 종료보고 후 "완료 노동자"를 참조한다 : 당신이 노동자에 연결된 이벤트 처리기가 될 때까지, 그래서
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