C# 在单独线程上运行窗体时.NET CF中的内存泄漏

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

编辑-测量精加工内存前为空的线程

这些都是在WindowsCE5.0下运行.NETCompactFramework2.0

我在开发我的应用程序时遇到了一些有趣的行为。每当我试图创建一个表单并让它运行一个单独的线程时,它关闭时似乎会泄漏392字节,我不确定为什么

到目前为止,我的方法是创建一个新线程,让它a)创建表单并不断调用Application.DoEvents,直到它关闭;b)创建表单并将其传递给Application.Run(表单)

下面是一个示例表单,说明了该问题

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字节的内存一次,它就会出现问题