0

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

“System.Windwos.Forms.dll”中出现“System.ComponentModel.Win32Exception”类型的未处理异常\附加信息:句柄无效

错误的控制台输出:

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

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

创建a 时,它会使用直接继承自此基本单词形式new transmitsubaddress的子类填充一个数组。baseWordForms当创建一个新表单时,它会调用它的InitializeComponent()函数,然后最终调用基类的InitializeComponenet()函数。

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

有什么方法可以让我的对象不会超出范围并收集垃圾?如果是这样,我将如何强制垃圾收集或找出将其保持在范围内的引用。

我希望这个伪代码可以清楚地说明我要描述的内容。本质上,我在运行这个程序时多次调用determineDataWordand 函数。ReadMessage在初始化该窗口表单数组时,我似乎在经过这么多次之后内存不足。我尝试在不初始化该数组的情况下运行程序,并且与我定义的 43 次相比,能够成功运行 2000 多次。这让我相信这些形式的某些东西阻止了它们被垃圾回收释放。当需要实际调用这些表单时,我会使用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
   }

}

在创建尝试捕获结构以捕获异常时,我收到错误消息,

“System.Drawing.dll”中出现“System.outOfMemoryException”类型的未处理异常“附加信息:内存不足”

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()"
4

1 回答 1

0

我找到了解决方案。如果有人遇到同样的问题,您需要在实例化新实例之前对这些表单对象中的每一个调用 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;
         }
     }
    }
}
于 2020-06-25T22:19:59.663 回答