【问题标题】:.NET Error Closing serial port BaseStream error is only available when the port is open.NET 错误关闭串行端口 BaseStream 错误仅在端口打开时可用
【发布时间】:2015-01-16 16:54:14
【问题描述】:

我正在使用 .NET System.IO.Ports.SerialPort,正如本文If you must use .NET System.IO.Ports.SerialPort中所建议的那样使用 BaseStream

但是当我尝试关闭端口或 baseStream 时,会引发 System.InvalidOperationException 说“BaseStream 仅在端口打开时可用”

这是我的代码:

    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();            
         }

我在某处读到串行端口应该在不同的线程上关闭,但我找不到,所以有什么想法吗??

谢谢!!

【问题讨论】:

  • 很有可能您实际上并没有打开端口,或者在其他地方关闭了它。如果没有a good code example,就无法说明比这更具体的内容了。
  • 很难看出重新实现 DataReceived 事件的意义。基本的错误是你继续调用 BeginRead(),即使你得到了告诉你端口已关闭的异常。
  • ActionStarted() 仅在 onLoad 事件上被调用,并且 port.close() 在窗口关闭之前不会被调用,所以,我在其他任何地方调用 beginRead,那不是案例,这就是为什么我要发布我的问题。谢谢
  • franko,我无法帮助您解决您的问题,但您是如何/在哪里实施 raiseAppSerialDataEvent(received)?

标签: c# .net stream serial-port


【解决方案1】:

我面临与您描述的相同的问题。基本上,我通过正确处理串行端口资源和在调用读取操作之前检查端口状态来解决。这是打开、读取和关闭端口的完整代码。

    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();
    }

【讨论】:

  • 鉴于在调用 Close() 的情况下使用了 SuppressFinzalize,这意味着您不会尝试重新打开()套接字?
【解决方案2】:

正如卢卡正确指出的那样,您应该在阅读之前检查串口的状态。

您收到异常是因为您的读取线程(委托)尝试使用关闭的串行端口。

此外,请在关闭串口之前使用 Dispose() 方法。一般来说,如果一个对象继承了 IDisposable,最好在不再需要它时将其释放,尤其是当对象使用串行端口等非托管资源时。即使在 C# 中,不释放非托管资源也会导致内存泄漏(垃圾收集器不会收集非托管资源!)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    相关资源
    最近更新 更多