据MSDN,该System.Windows.Forms.WebBrowser控件是为ActiveX WebBrowser控件托管包装,并会使用任何版本的控件安装在用户的计算机上。
你可以找到的Dispose(布尔)在web浏览器类(在Visual Stuio按F12键)来释放非托管资源的元数据方法。(不要将其())
代码here
protected override void Dispose(bool disposing) {
if (disposing) {
if (htmlShimManager != null)
{
htmlShimManager.Dispose();
}
DetachSink();
ActiveXSite.Dispose();
}
base.Dispose(disposing);
}
但是,如果您尝试调用WebBrowser.Dispose(bool),则会显示编译器错误CS1540。
WebBrowser类支持Dispose(bool)方法,但我们不能使用它。
我认为WebBrowser类的设计是错误的。
我有一个想法来调用WebBrowser.Dispose(true)。
这很简单!但它不是一个好方法。在这里
示例代码(3个按钮和文本框1个需要)
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace Test_20170308_01
{
public partial class Form1 : Form
{
[DllImportAttribute("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
private static extern int SetProcessWorkingSetSize(IntPtr process, int minimumWorkingSetSize, int maximumWorkingSetSize);
public static void FlushMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
}
public Form1()
{
InitializeComponent();
}
private void addWeb()
{
WebBrowserD webBrowser1 = new WebBrowserD();
webBrowser1.Size = new Size(1070, 585);
this.Controls.Add(webBrowser1);
webBrowser1.Navigate("about:blank");
}
private void RemoveWeb()
{
foreach (Control ctrl in this.Controls)
{
if (ctrl is WebBrowserD)
{
WebBrowserD web = (WebBrowserD)ctrl;
this.Controls.Remove(ctrl);
web.Navigate("about:blank");
web.Dispose(true);
FlushMemory();
}
}
}
private void button1_Click(object sender, EventArgs e)
{
addWeb();
}
private void button2_Click(object sender, EventArgs e)
{
RemoveWeb();
}
private void button3_Click(object sender, EventArgs e)
{
foreach (Control ctrl in this.Controls)
{
if (ctrl is WebBrowserD)
{
WebBrowserD axweb = (WebBrowserD)ctrl;
axweb.Navigate(textBox1.Text);
FlushMemory();
}
}
}
}
public class WebBrowserD : WebBrowser
{
internal void Dispose(bool disposing)
{
// call WebBrower.Dispose(bool)
base.Dispose(disposing);
}
}
}
此代码,可以防止内存泄漏。
综上所述, 你只需要一类。
public class WebBrowserD : WebBrowser
{
internal void Dispose(bool disposing)
{
base.Dispose(disposing);
}
}
还有,如果你的事件处理程序添加到任何的导航元素的内存泄漏。为了解决这个问题,你必须保留所有元素的字典(也包括顶级文档),然后在OnDocumentCompleted()函数中,逐个删除事件处理程序,同时在调用marshall.ReleaseComObject(o.DomDocument)循环,然后通过Marshal.ReleaseComObject(document.DomDocument)最终释放顶层文档。 – Brain2000 2017-04-10 17:07:40