【发布时间】:2013-12-02 18:11:48
【问题描述】:
我该怎么做?
在破坏我的意思是从内存中删除它。
一个例子(Form1 是某种形式):
static void Main()
{
Test();
// here we still have A alive
// GC.Collect() doesn't helps
Form1 B = new Form1();
Application.Run(B);
// problem is here: B and A "collides", due to assumption what A is already dead
}
public static Test()
{
Form1 A = new Form1();
// do something with A, but not displaying form
// I was sure what A will disappears after Test()
}
问题可能出在表单上使用的某些组件上吗?计时器,在构造函数中创建?还是 A 存在那么久的正常方式?
更新
碰撞 - 意味着他们正在使用仅供单个用户使用的东西。如何push从内存中删除 A 的过程?
请不要着急(感谢-2),我在工作,所以不能快速更新。我尽量说清楚。
只要可以,请避免使用陈词滥调GC.Collect 总是不好的,等等。我知道。正如您所看到的,我需要在软件运行之前对表单进行某种操作,因此预计不会出现性能或任何其他类型的问题。这可能不是最好的情况,但请告诉我更好的情况。对 A 做某事是必要的测试,是的。
问题是:在对 A 进行测试后,我希望它消失。当然,我可以修改 A 的方式,使其没有计时器、组件等。但是已经有几十种形式了。一切都必须经过测试。而且我根本不知道在 Test() 之后 A 会存在什么。
更新 2
我真的很想知道为什么 question 有 -3。我今天学到的是当你创建一个表单时,它会一直存在到应用程序结束,现在有已知的方法可以杀死它。在构造函数中创建的计时器将继续运行,组件将尝试访问它们不应该访问的东西,等等。只要您愿意创建工作(看起来)表单的第二个实例,很多事情都会发生变化。
更新 3
让我们做一个简单的测试:
static class Program
{
public static bool Test { get; set; }
static void Main()
{
DoTest();
Test = true;
Application.Run(new Form1());
}
static void DoTest()
{
var A = new Form1();
var B = new Form1();
var C = new Form1();
//A.Dispose();
//B.Dispose();
//C.Dispose();
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (Program.Test)
{
timer1.Stop();
MessageBox.Show("123");
}
}
}
它将显示 4 个消息框(来自主窗口和来自 undead A、B、C)。在今天之前,我百分百确定,我在表格上写的任何东西都会和表格一起被删除。每当我创建一个局部变量时——它将是局部的。但似乎并非如此。这是一个问题 - 不明显的行为。
看起来Dispose() 的 Thorsten Dittmar 解决方案应该可以解决问题。我应该检查自己的组件(手动关闭它们的计时器等)。
【问题讨论】:
-
B and A "collides"是什么意思 -
你能定义“碰撞”吗?表格 A 将保留在内存中,直到 GC 另有决定。如果你有很多内存,这可能需要几天......
-
在创建第一个
Form时会发生很多疯狂的事情。对A的多次引用被保存在winforms 代码的某个深处,我一点也不感到惊讶。我建议你找到一种不同的方式来做你想做的任何事情。也许如果你告诉我们那是什么,你会得到更好的答案。 -
GC.Collect()几乎总是一个错误。 -
顺便说一句。如果您在不显示表单 A 的情况下执行某些操作,然后运行 Application.Run(B),那么您将遇到严重的设计问题。或者这只是某种测试?
标签: c# winforms garbage-collection destructor