为了账号安全,请及时绑定邮箱和手机立即绑定

使用串行端口时,出现错误:尝试读取或写入受保护的内存

使用串行端口时,出现错误:尝试读取或写入受保护的内存

C#
慕斯王 2021-06-02 14:58:12
我知道以前有人问过这个问题,但现有的答案都没有解决我的问题。我有一个 WinForms 应用程序,它与许多设备进行通信,获取数据并将它们写入文件。它打开 GPIB 和串行端口通信,最后关闭所有这些。我使用this.Dispose()并this.Close()确保释放内存(至少我认为内存已释放)。但是,下次我运行它时,几个小时后我收到错误:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。如果我再次运行它,崩溃时间会变得越来越短,就像内存中积累了一些东西一样。我复制了似乎与此问题相关的部分代码。我在内存消耗方面犯了任何错误吗?我试过的:添加this.Dispose()和Close()关闭端口的功能(最初我忘记添加它们)。但仍然没有帮助。我还尝试在每次运行之前重新启动计算机,但它也没有帮助。public partial class Form1 : Form{    //GPIB and serial ports    SerialPort Arduino;    SerialPort serialPort1 = new SerialPort();    private Device DMM1, DMM2, DMM3;    private Address DMM1_Address, DMM2_Address, DMM3_Address;    private Address[] Address_List = new Address[3];    private AddressCollection GPIB_Adds;    Board GPIB = new Board(0);    //Timers    System.Windows.Forms.Timer fire_time = new System.Windows.Forms.Timer();    System.Windows.Forms.Timer measurement_time = new System.Windows.Forms.Timer();    System.Windows.Forms.Timer preparation_delay = new System.Windows.Forms.Timer();    System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();    public Form1()    {        // ...some code    }    private void InitializePorts()    {        // ...ports are initialized here    }    private void button1_Click(object sender, EventArgs e)    {       preparation_delay.Interval = 1000;       preparation_delay.Tick += new EventHandler(start);       preparation_delay.Start();       measurement_time.Interval = 60000;       measurement_time.Tick += new EventHandler(stop);       fire_time.Interval = Convert.ToInt32(textBox6.Text) * 1000;       fire_time.Tick += new EventHandler(FIRE);        }    }    private void start(object obj, EventArgs e)    {        stopwatch.Start();        measurement_time.Start();        fire_time.Start();        preparation_delay.Stop();        preparation_delay.Tick -= new EventHandler(start);        //Here I try to annihilate the event handler in fear of staying in memory    }
查看完整描述

2 回答

?
回首忆惘然

TA贡献1847条经验 获得超11个赞

对于本机 NET 对象,原则上您不需要显式调用 Dispose(终结器会这样做),但是如果您有一些外部对象访问外部资源(GPIB?),则必须小心。我看到的是,如果 Write_To_Text 中有异常,您将调用 GPIB.Dispose 两次,并且可以在计时器有效停止之前调用它。确保在处理后不会调用任何 Gpib 函数(例如设置一个标志,在调用 Gpib 函数之前将检查该标志)。


查看完整回答
反对 回复 2021-06-05
  • 2 回答
  • 0 关注
  • 327 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信