C# 在单独线程上运行窗体时.NET CF中的内存泄漏
编辑-测量精加工内存前为空的线程 这些都是在WindowsCE5.0下运行.NETCompactFramework2.0 我在开发我的应用程序时遇到了一些有趣的行为。每当我试图创建一个表单并让它运行一个单独的线程时,它关闭时似乎会泄漏392字节,我不确定为什么 到目前为止,我的方法是创建一个新线程,让它a)创建表单并不断调用Application.DoEvents,直到它关闭;b)创建表单并将其传递给Application.Run(表单) 下面是一个示例表单,说明了该问题C# 在单独线程上运行窗体时.NET CF中的内存泄漏,c#,.net,compact-framework,memory-leaks,C#,.net,Compact Framework,Memory Leaks,编辑-测量精加工内存前为空的线程 这些都是在WindowsCE5.0下运行.NETCompactFramework2.0 我在开发我的应用程序时遇到了一些有趣的行为。每当我试图创建一个表单并让它运行一个单独的线程时,它关闭时似乎会泄漏392字节,我不确定为什么 到目前为止,我的方法是创建一个新线程,让它a)创建表单并不断调用Application.DoEvents,直到它关闭;b)创建表单并将其传递给Application.Run(表单) 下面是一个示例表单,说明了该问题 public part
public partial class TestForm : Form
{
public TestForm()
{
InitializeComponent();
}
private void DoMemoryTest(bool useApplicationRun)
{
GC.WaitForPendingFinalizers();
GC.Collect();
long originalMem = GC.GetTotalMemory(true);
Thread t;
if (useApplicationRun)
t = new Thread(new ThreadStart(AppRunThread));
else
t = new Thread(new ThreadStart(DoEventThread));
t.Start();
Thread.Sleep(3000);//Dodgey hack
t.Join();
t = null;
GC.WaitForPendingFinalizers();
GC.Collect();
long terminatingMem = GC.GetTotalMemory(true);
MessageBox.Show(String.Format("An increase of {0} bytes was measured from {1} bytes",
terminatingMem - originalMem, originalMem));
}
private void button1_Click(object sender, EventArgs e)
{
DoMemoryTest(false);
}
private void button2_Click(object sender, EventArgs e)
{
DoMemoryTest(true);
}
private void AppRunThread()
{
Application.Run(new OpenCloseForm());
}
private void DoEventThread()
{
using (OpenCloseForm frm = new OpenCloseForm())
{
frm.Show();
do
{
Application.DoEvents();
} while (frm.Showing);
}
}
/// <summary>
/// Basic form that opens for a short period before shutting itself
/// </summary>
class OpenCloseForm : Form
{
public OpenCloseForm()
{
this.Text = "Closing Soon";
this.Size = new Size(100, 100);
this.TopMost = true;
}
public volatile bool Showing = false; //dodgy hack for DoEventThread
System.Threading.Timer timer;
protected override void OnLoad(EventArgs e)
{
Showing = true;
base.OnLoad(e);
timer = new System.Threading.Timer(new TimerCallback(TimerTick), null, 1000, 1000);
}
delegate void CloseDelegate();
private void TimerTick(object obj)
{
this.Invoke(new CloseDelegate(this.Close));
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
Showing = false;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (timer != null)
{
timer.Dispose();
timer = null;
}
}
base.Dispose(disposing);
}
}
//Designer code to follow....
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.timer1 = new System.Windows.Forms.Timer();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(32, 47);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(116, 39);
this.button1.TabIndex = 1;
this.button1.Text = "DoEvents Loop";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// button2
//
this.button2.Location = new System.Drawing.Point(32, 115);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(116, 39);
this.button2.TabIndex = 2;
this.button2.Text = "Application.Run";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// TestForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoScroll = true;
this.ClientSize = new System.Drawing.Size(177, 180);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "TestForm";
this.Text = "TestForm";
this.TopMost = true;
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button2;
}
公共部分类TestForm:Form
{
公共测试表单()
{
初始化组件();
}
私有void DoMemoryTest(bool useApplicationRun)
{
GC.WaitForPendingFinalizers();
GC.Collect();
long originalMem=GC.GetTotalMemory(true);
螺纹t;
如果(使用应用程序运行)
t=新线程(新线程开始(AppRunThread));
其他的
t=新线程(新线程开始(DoEventThread));
t、 Start();
Thread.Sleep(3000);//道奇黑客
t、 Join();
t=零;
GC.WaitForPendingFinalizers();
GC.Collect();
long terminatingMem=GC.getTotalMemy(true);
Show(String.Format)(“从{1}字节增加了{0}字节”,
终止mem-originalMem,originalMem));
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
domenorytest(假);
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
DoMemoryTest(真实);
}
私有void AppRunThread()
{
运行(新的OpenCloseForm());
}
私有void DoEventThread()
{
使用(OpenCloseForm frm=new OpenCloseForm())
{
frm.Show();
做
{
Application.DoEvents();
}同时(首次展示);
}
}
///
///在自动关闭之前打开一小段时间的基本窗体
///
类OpenCloseForm:Form
{
公共OpenCloseForm()
{
此.Text=“即将关闭”;
该尺寸=新尺寸(100100);
this.TopMost=true;
}
public volatile bool Showing=false;//DoEventThread的狡猾攻击
系统线程定时器;
受保护的覆盖无效加载(事件参数e)
{
显示=真实;
基础荷载(e);
timer=new System.Threading.timer(new TimerCallback(TimerTick),null,10001000);
}
delegate void CloseDelegate();
私有void TimerTick(对象对象对象)
{
this.Invoke(newclosedelegate(this.Close));
}
关闭时受保护的覆盖无效(事件参数e)
{
基础。一旦关闭(e);
显示=假;
}
受保护的覆盖无效处置(布尔处置)
{
如果(处置)
{
如果(计时器!=null)
{
timer.Dispose();
定时器=空;
}
}
基地。处置(处置);
}
}
//要遵循的设计器代码。。。。
///
///必需的设计器变量。
///
private System.ComponentModel.IContainer components=null;
///
///清理所有正在使用的资源。
///
///如果应释放托管资源,则为true;否则为false。
受保护的覆盖无效处置(布尔处置)
{
if(处理和(组件!=null))
{
组件。Dispose();
}
基地。处置(处置);
}
#区域Windows窗体设计器生成的代码
///
///设计器支持所需的方法-不修改
///此方法的内容与代码编辑器一起使用。
///
私有void InitializeComponent()
{
this.timer1=new System.Windows.Forms.Timer();
this.button1=new System.Windows.Forms.Button();
this.button2=new System.Windows.Forms.Button();
这个.SuspendLayout();
//
//按钮1
//
this.button1.Location=新系统图纸点(32,47);
this.button1.Name=“button1”;
this.button1.Size=新系统图纸尺寸(116,39);
this.button1.TabIndex=1;
this.button1.Text=“DoEvents循环”;
this.button1.Click+=新系统.EventHandler(this.button1\u Click);
//
//按钮2
//
this.button2.Location=新系统图纸点(32115);
this.button2.Name=“button2”;
this.button2.Size=新系统图纸尺寸(116,39);
this.button2.TabIndex=2;
this.button2.Text=“Application.Run”;
this.button2.Click+=新系统.EventHandler(this.button2\u Click);
//
//测试表格
//
this.AutoScaleDimensions=新系统.Drawing.SizeF(96F,96F);
this.AutoScaleMode=System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoScroll=true;
this.ClientSize=新系统.Drawing.Size(177180);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name=“TestForm”;
this.Text=“TestForm”;
this.TopMost=true;
此选项为.resume布局(false);
}
#端区
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Button按钮1;
private System.Windows.Forms.Button按钮2;
}
我是否遗漏了一些关于控制措施处置的信息?有没有人对这件事有什么想法
提前感谢。我可能错了,因为我不是CF方面的专家,但是.net不一定会释放它占用的内存,除非系统处于内存压力之下 我的理解是,如果应用程序需要x字节的内存一次,它就会出现问题