何时对这些对象进行垃圾回收

本文关键字:对象 何时 | 更新日期: 2023-09-27 18:33:33

我创建了以下扩展方法,以便在使用 WebBrowser 控件时等待页面加载。

public static Task<bool> WaitLoad(this WebBrowser webBrowser, int wait)
    {
        var timerInternalWait = new Timer {Interval = 1000, Tag = "Internal"};
        var timerMaxWait = new Timer {Interval = wait};
        var tcs = new TaskCompletionSource<bool>();
        WebBrowserNavigatingEventHandler navigatingHandler = (sender, args) => timerInternalWait.Stop();
        webBrowser.Navigating += navigatingHandler;
        WebBrowserDocumentCompletedEventHandler documentCompletedHandler = (sender, args) => { timerInternalWait.Stop(); timerInternalWait.Start(); };
        webBrowser.DocumentCompleted += documentCompletedHandler;
        EventHandler timerHandler = null;
        timerHandler = (sender, args) =>
        {
            webBrowser.Navigating -= navigatingHandler;
            webBrowser.DocumentCompleted -= documentCompletedHandler;
            timerInternalWait.Tick -= timerHandler;
            timerMaxWait.Tick -= timerHandler;
            timerMaxWait.Stop();
            timerInternalWait.Stop();
            tcs.SetResult(((Timer) sender).Tag.ToString() == "Internal");
        };
        timerInternalWait.Tick += timerHandler;
        timerMaxWait.Tick += timerHandler;
        return tcs.Task;
    }

不过,我有几个问题:

什么时候(如果有的话)计时器不复存在并被GCed?我想同样的问题也适用于 lambda 表达式。

如果目前的答案是永远不会,我能做些什么来确保在不再需要时清理它们?

最后,ReSharper给了我一个关于navigatingHandlerdocumentCompletedHandler定义的implicitly captured closure。如何防止这种情况发生?

何时对这些对象进行垃圾回收

非常棘手的问题。

在您返回的任务完成之前,不会对您的计时器进行垃圾回收。

为什么?好的,这是棘手的部分。那是因为ReSharper告诉你的关闭!

lambda 内部使用的所有变量都由框架保持活动状态,并带有引用,以确保它们在执行 lambda 时存在并恢复它们以供其使用。因为您在 lambda 中使用计时器,所以当 lambda 存在时,计时器将保持活动状态,并且 lambda 至少会存在,直到执行 lambda 的最后一行,从而设置任务的结果。

因此,可以肯定的是,在执行 lambda 之前,计时器将保持活动状态。