Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Error Closing serial port BaseStream error is only available when the port is open

I'm using the .NET System.IO.Ports.SerialPort using the BaseStream as suggested in this post If you must use .NET System.IO.Ports.SerialPort

But when I try to close the port or the baseStream, an System.InvalidOperationException is raised saying "The BaseStream is only available when the port is open"

This is my code:

    private void ActionStarted()
    {
        //ajusta el puerto
        setupSerial();

        serial.Open();  //conecta al plc
        byte[] buffer = new byte[15];
        Action kickoffRead = null;

        if (serial.IsOpen) 
        {
            kickoffRead = delegate()
            {
                serial.BaseStream.BeginRead(buffer, 0, buffer.Length,
                    delegate(IAsyncResult ar)
                    {
                        try
                        {
                            int actualLength = serial.BaseStream.EndRead(ar);
                            byte[] received = new byte[actualLength];
                            Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
                            raiseAppSerialDataEvent(received);
                        }
                        catch 
                        {
                           //do something
                        }

                        kickoffRead();

                    }, null);
            };
            kickoffRead();
        }

    }

//<-- here is where the error occurs -->
 private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
        serial.BaseStream.Flush();
        serial.BaseStream.Close();
        serial.Close();            
         }

I read somewhere that the serial port should be close on a different thread but I can't find that, so any thoughts??

Thanks!!

like image 815
franko_camron Avatar asked Dec 12 '25 11:12

franko_camron


1 Answers

I face the same problem as you described. Basically I solved with a proper disposal of the serial port resources and a check on port status before calling reading action. Here is the full code that open the port, read and close it.

    public bool Open()
    {
        bool result = false;
        try
        {

            this.serialPort.Open();
            result = true;
            startReading = StartAsyncSerialReading;
            startReading();
        }
        catch (Exception)
        {
            this.Close();
            result = false;
        }
        return result;

    }

    private void StartAsyncSerialReading()
    {
        byte[] buffer = new byte[bufferLength];

        serialPort.BaseStream.BeginRead(buffer, 0, bufferLength, delegate(IAsyncResult ar)
        {
            try
            {
                if (serialPort.IsOpen)
                {
                    actualReadLength = serialPort.BaseStream.EndRead(ar);                        
                    received = new byte[actualReadLength];

                    DoYourStuffWithDataBuffer();
                }
            }

            catch (IOException exc)
            {
                //handleAppSerialError(exc);
            }

            if (serialPort.IsOpen)
                startReading();

        }, null);

    }

    protected Stream GetStream()
    {
        return this.serialPort.BaseStream;
    }

    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)                
                this.serialPort.Dispose();

            this.disposed = true;
        }
    }

    public void Close()
    {
        this.serialPort.Close();
        this.Dispose();
    }
like image 107
Luca Del Tongo Avatar answered Dec 14 '25 01:12

Luca Del Tongo