何时对这些对象进行垃圾回收
本文关键字:对象 何时 | 更新日期: 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给了我一个关于navigatingHandler
和documentCompletedHandler
定义的implicitly captured closure
。如何防止这种情况发生?
非常棘手的问题。
在您返回的任务完成之前,不会对您的计时器进行垃圾回收。
为什么?好的,这是棘手的部分。那是因为ReSharper告诉你的关闭!
lambda 内部使用的所有变量都由框架保持活动状态,并带有引用,以确保它们在执行 lambda 时存在并恢复它们以供其使用。因为您在 lambda 中使用计时器,所以当 lambda 存在时,计时器将保持活动状态,并且 lambda 至少会存在,直到执行 lambda 的最后一行,从而设置任务的结果。
因此,可以肯定的是,在执行 lambda 之前,计时器将保持活动状态。