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

我知道以前有人问过这个问题,但现有的答案都没有解决我的问题。我有一个 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

    }

慕斯王
浏览 328回答 2
2回答

回首忆惘然

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