当前位置:  开发笔记 > 编程语言 > 正文

什么时候我的BackgroundWorker实例将被垃圾收集

如何解决《什么时候我的BackgroundWorker实例将被垃圾收集》经验,为你挑选了1个好方法。

考虑这个代码块

public void ManageInstalledComponentsUpdate()
        {
            IUpdateView view = new UpdaterForm();
            BackgroundWorker worker = new BackgroundWorker();
            Update update = new Update();
            worker.WorkerReportsProgress = true;
            worker.WorkerSupportsCancellation = true;
            worker.DoWork += new DoWorkEventHandler(update.DoUpdate);
            worker.ProgressChanged += new ProgressChangedEventHandler(view.ProgressCallback);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(view.CompletionCallback);            
            worker.RunWorkerAsync();
            Application.Run(view as UpdaterForm);     
        }

这一切都很好,但我想了解为什么对象(工作者,视图和更新)不会收集垃圾



1> Marc Gravell..:

线程计为根对象; 我不确切知道BackgroundWorker是如何操作的,但似乎主线程方法将在worker实例上访问状态; 因此,工作线程本身将使BackgroundWorker实例保持活动状态,直到(至少)线程退出为止.

当然; 集合还要求所有其他(实时)对象都取消引用工作对象; 另请注意,堆栈变量的集合在调试/发布中可能有所不同,并且附加/不附带调试器.

[编辑]正如也已经注意到的那样; worker(在你的代码中)上的事件处理程序将使"视图"和"更新"对象保持活动状态(通过委托),但不是相反.只要工作者的生命比"视图"和"更新"更短,您就不需要对取消订阅事件感到偏执.我已编辑代码以包含一个"SomeTarget"对象,该对象仅由worker引用:您应该看到此效果(即目标与worker一起死亡).

当线程死亡时,工人被收集:这是证据; 在工人报告退出后你应该看到"工人最终确定":

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());
    }
}

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有