C# 对象不会超出范围并导致系统崩溃



我遇到了一个奇怪的情况,当我在几次迭代中最终将对象变量重新分配给新实例时,我似乎内存不足。我收到错误:

"System.Windwos.Forms.dll"中发生了类型为"System.ComponentModel.Win32Exception"的未处理异常 其他信息:句柄无效

控制台输出来自错误:

我尝试在网上查找该错误消息,有些人似乎认为,"您可能泄漏了句柄,可能是由于没有正确关闭窗口或处置控件。 但是,我不是在打开窗口,我只是在实例化窗口窗体的新对象实例。由于代码的性质,我无法共享它,但我可以大致了解导致错误的原因。

本质上,在我的主窗体中,我创建了一个名为TransmitMessage的类,在此类中,它有一个名为BaseSubaddress的基类对象,用于保存称为TransmitSubaddress的不同类型的子类(直接从basesubaddress继承(。每次我想处理一条消息时,类都会使用一个函数来确定要分配哪个TransmitSubaddress(1、2 或 3(,每个子地址都有自己的特定例程。它将创建此对象的新实例,并将其分配给 baseSubaddress 变量。

创建new transmitsubaddress时,它会使用直接从此基本词形式继承的子类填充baseWordForms数组。创建新窗体时,它会调用其InitializeComponent()函数,然后最终调用基类的InitializeComponenet()函数。

当我尝试第 43 次发送消息时,发生了错误。特别是在尝试填充此数组时。

有没有办法让我的对象不会超出范围并被垃圾回收?如果是这样,我将如何强制垃圾收集或找出将其保留在范围内的引用。

我希望这个伪代码可以澄清我试图描述的内容。从本质上讲,我在运行该程序时多次调用determineDataWordReadMessage函数。似乎在初始化该窗口表单数组时,经过这么多次之后,我的内存不足。我尝试在不初始化该数组的情况下运行该程序,并且能够获得 2000+ 次成功运行,而我定义了 43 次。这让我相信这些形式的某些东西正在阻止它们被垃圾收集释放。当需要实际调用这些表单时,我使用Using关键字来尝试避免此问题。

Main form{
TransmitMessage Tmsg;
private void determineDataWord(){
//logic for determining words
tmsg = new transmitMessage(//stuff about transmitmessage);
}
private void readMessage(){
//logic for reading words
tmsg.translateTMsage(//stuff about message)
} 
}
class TransmitMessage{
baseSubaddress Tsubaddress;
private void translateTMsage(//logic for msg){
//logic for translation
assignSubaddr(//info about msg);
Tsubaddress.Translate(//infor about msg);
}    
private void assignSubaddr(//info about msg){
//logic for determining subaddress    
Tsubaddress = new TransmitSubaddress(1,2,3...);
}   
}
class TransmitSubaddress : baseSubaddress{
this.datawords = new baseWordForms[x]{new wordForm1, new wordfrom2....};
public void Translate(){
//logic for translation
}
}

在创建一个 try catch 结构来捕获异常时,我收到错误消息,

"系统绘图.dll中发生"系统.内存异常"类型的未处理异常 "附加信息: 内存不足">

error stack at system.windows.forms.ContrainerControl.GetFontAutoScakeDimensions()
at system.windows.forms.ContrainerControl.get_CurrentAutoScaleDimensions()
at system.windows.forms.ContrainerControl.get_AutoScaleFactor()
at system.windows.forms.ContrainerControl.PerformAutoScale(Boolean includedBounds, Boolean excludeBounds)
at system.windows.forms.ContrainerControl.PerformNeededAutoScaleOnLayout()
at system.windows.forms.Form.OnLayout(LayoutEventArgs Ievent)
at system.windows.forms.control.PerformLayout(LayoutEventArgs args)
at system.windows.forms.control.System.Windows.Forms.Layout.IArrangedElement.PerformLayout(IArrangedElement affectedElement,String affectedProperty)
at system.windows.forms.ContainerControl.LayoutScalingNeeded()
at system.windows.forms.ContainerControl.set_AutoScaleMode(AutoscaleMode Value)
at "xxx.baseDataWordForm.InitilizaComponent()"

我找到了解决方案。如果有人遇到同样的问题,您需要在实例化新实例之前对每个表单对象调用 dispose(( 方法。

//strictly psudocode don't attempt to run
class TransmitMessage{
baseSubaddress Tsubaddress;
private void translateTmesage(//logic for msg){
//logic for translation
assignSubaddr(//info about msg);
Tsubaddress.Translate(//infor about msg);
}    
private void assignSubaddr(//info about msg){
//logic for determining subaddress   
ClearWords(int numberOfWords) 
Tsubaddress = new TransmitSubaddress(1,2,3...);
}   
private void ClearWords(int numberOfWords){
if (Tsubaddress != null){
for(int i = 0; i< numberOfWords; i++){
Tsubaddress.dataWords[i].dispose;
}
}
}
}

最新更新