0

USBポートを介してテキストを送信しているArduinoから読んでいます。Arduino は、その出力のステータスを毎秒送信します。コマンド受信イベントで、いくつかのチェックボックス (シャッターが開いている、電源がオン、またはライトがオン) を設定し、受信したデータを複数行のテキスト ボックスに出力します。
とにかく....すべてが数秒間機能し、その後速度が低下し、最終的に約10分後にメモリ不足の例外が発生します。何が問題なのかわかりません。シリアルデータを読み取るクラスにあると思います-これがそのコードです。

using System;
using System.IO.Ports;

namespace WOCA.Core.SerialComms
{
    internal class ArduinoCommunicator : ICommunicator
    {
        public event EventHandler<CommsEventsArg> CommandReceived;

    internal ArduinoCommunicator(string comPort)
    {
        Port = new SerialPort(comPort) {BaudRate = 9600, DtrEnable = true};
        Port.DataReceived += PortOnDataReceived;
    }

    private SerialPort Port { get; set; }


    public bool IsOpen { get; set; }


    public void Open()
    {
        try
        {
            if (!Port.IsOpen)
            {
                Port.Open();
                IsOpen = true;
            }
            else
            {
                throw new InvalidSerialCommsException("Serial port already open");
            }
        }
        catch (Exception ex)
        {
            throw new InvalidSerialCommsException("Serial Port error: " + ex.Message);
        }
    }

    public void Close()
    {
        try
        {
            if (Port.IsOpen)
            {
                Port.Close();
                IsOpen = false;
            }
            else
            {
                throw new InvalidSerialCommsException("Serial port not open");
            }
        }
        catch (Exception)
        {

            throw new InvalidSerialCommsException("Serial port error");
        } 

    }

    public void SendCommand(string command)
    {
        try
        {
            if (Port.IsOpen)
            {
                Port.Write(command);
            }
            else
            {
                throw new InvalidSerialCommsException("Serial port not open");
            }
        }
        catch (Exception)
        {

            throw new InvalidSerialCommsException("Serial port error, the command has not been sent");
        }

    }

    private void PortOnDataReceived(object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs)
    {
        SerialPort serialPort = sender as SerialPort;

        if (serialPort != null)
        {
            string command = serialPort.ReadLine();
            command = command.Remove(command.Length-1,1);
            CommsEventsArg args = new CommsEventsArg(command);
            OnCommandReceived(args);
        }
    }

    protected virtual void OnCommandReceived(CommsEventsArg e)
    {
        EventHandler<CommsEventsArg> handler = CommandReceived;
        if (handler != null)
        {
            handler(this, e);
        }
    }
}

}

4

1 に答える 1

0

これは、SerialPort クラスの実装が原因である可能性があります。他のスレッドに制御を渡すことは決してないため、ファイナライズ スレッドはオブジェクトをファイナライズしてメモリを解放できません。それについての私の記事を参照してください: http://alexatnet.com/articles/net-memory-management-and-garbage-collector#best-practices

それを修正するには、追加する必要があります

Thread.CurrentThread.Join(100)

たとえば、 に追加される場合がありますPortOnDataReceived。これにより、ファイナライズ スレッドが保留中のファイナライザーを実行できるようになります。

于 2013-11-01T03:10:33.497 に答える