什么时候这些对象被垃圾收集

时间:2016-02-06 17:02:19

标签: c# garbage-collection webbrowser-control resharper

我创建了以下扩展方法,以便在使用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;
    }

我有几个问题:

如果有的话,定时器何时停止存在并获得GC?我想同样的问题适用于lambda表达式。

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

最后,ReSharper在implicitly captured closurenavigatingHandler定义上给了我一个documentCompletedHandler。我怎样才能防止这种情况发生?

1 个答案:

答案 0 :(得分:0)

非常棘手的问题。

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

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

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

所以它确定假定计时器将保持活着,直到lambda被执行。