根据MSDN, System.Windows.Forms.WebBrowser 控件是 ActiveX WebBrowser 控件的托管包装,并使用安装在用户计算机上的任何版本的控件。
您可以在 WebBrowser 类的元数据中找到Dispose(bool)方法(在 Visual Stuio 中按 F12)来释放非托管资源。(不是 Dispose())
这里的代码
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);
}
}