簡體   English   中英

.NET中的SerialPort是非托管資源嗎? 我的包裝課程是否正確?

[英]Is SerialPort in .NET unmanaged resource? Is my wrapped class correct?

我在串口類上有適配器模式(包裝器)。 我應該實現IDisposable模式並在其中調用_wrappedSerialPort.Dispose()嗎? 有我的班級,這是對的嗎?

public class SerialPortAdapter : ISerialPortAdapter
{
    private bool _disposed;

    public event SerialDataReceivedEventHandler DataReceived;

    private readonly SerialPort _wrappedSerialPort;

    public SerialPort WrappedSerialPort
    {
        get { return _wrappedSerialPort; }
    }

    public string PortName
    {
        get { return _wrappedSerialPort.PortName; }
        set { _wrappedSerialPort.PortName = value; }
    }

    public BaudRate BaudRate
    {
        get { return (BaudRate)Enum.ToObject(typeof(BaudRate), _wrappedSerialPort.BaudRate); }
        set { _wrappedSerialPort.BaudRate = (int)value; }
    }

    public bool IsOpen
    {
        get { return WrappedSerialPort.IsOpen; }
    }

    public SerialPortAdapter(SerialPort serialPort)
    {
        _wrappedSerialPort = serialPort;
        _wrappedSerialPort.DataReceived += SerialPortDataReceived;
    }

    public void OpenPort()
    {
        if (!_disposed)
        {
            if (!WrappedSerialPort.IsOpen)
            {

                WrappedSerialPort.Open();

            }
        }
    }


    public void ClosePort()
    {
        if (!_disposed)
        {
            if (WrappedSerialPort.IsOpen)
            {

                WrappedSerialPort.Close();

            }
        }
    }


    public void WriteLine(string request)
    {
    ...
    }


    public void Write(byte[] request)
    {
       ....
    }


    public byte[] Read()
    {
      ....
    }


    public string ReadLine()
    {
       ...
    }


    private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (DataReceived != null)
        {
            DataReceived(this, e);
        }
    }

    #region IDisposable Members

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

    private void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // Dispose managed resources.

            }
            // Dispose unmanaged resources.

            ClosePort();
            WrappedSerialPort.DataReceived -= SerialPortDataReceived;
            _wrappedSerialPort.Dispose();

            _disposed = true;

        }
    }

    ~SerialPortAdapter()
    {

        Dispose(false);
    }

    #endregion
}

編輯:是否有必要調用它,或者只調用_wrappedSerialPort.Dispose();?

        ClosePort();
        WrappedSerialPort.DataReceived -= SerialPortDataReceived;
        _wrappedSerialPort.Dispose();

SerialPort本身是非托管資源的所有者,這就是它實現完整的 Disposable模式的原因。

在您的類中, _wrappedSerialPort是受資源。 我的定義: 托管資源是間接的非托管資源

您的類並不需要完整的圖案。 您可以而且應該省略析構函數(或終結器), ~SerialPortAdapter () ,然后您可以跳過SupressFinalize。

最好留下其余的,但你會發現很容易縮短代碼(因為void Dispose(bool)永遠不會被調用false )。

Henk Holterman的答案是正確的:SerialPort是一個托管資源,它本身擁有一個非托管資源,因此實現了IDisposable

由於您的包裝器擁有一個SerialPort,它間接擁有Seri​​alPort的非托管資源,因此必須實現IDisposable。 您的實現是錯誤的,只有在disposing為true時才應該處置擁有的SerialPort實例,因為它是一個托管資源。

它應該實現如下:

   private void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // Dispose managed resources.
                ClosePort();
                WrappedSerialPort.DataReceived -= SerialPortDataReceived;
                _wrappedSerialPort.Dispose();
            }
            _disposed = true;
        }
    }

另外,正如Henk Holterman所指出的,如果你直接擁有非托管資源,你只需要一個析構函數,這不是這里的情況,你可以通過去掉析構函數來簡化IDisposable實現。

是的,在這種情況下,您實現Dispose方法是正確的。 確保將IDisposable添加到您的類聲明中。 這使得可以使用非常方便的using構造,如下所示:

using (var port = new SerialPortAdapter(serialPort)) {
    port.OpenPort();
    // use port
}

在包裝的串口上調用Dispose應該足夠了,因為這將關閉端口。 根據MS文檔, Close將在內部調用Dispose 但是,通過明確地調用Close來明確你的意圖是沒有害處的。

從事件中取消注冊,就像你正在做的那樣,是一種很好的做法。

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.close.aspx

  • 是的,串行底池是一個非托管報告。 或者你有沒有看過物理硬件的垃圾收集器? ;)

  • 實現IDisposable的訪問類顯示了這一點 - 這意味着您的類主持一個lon term refernce很多,而且實現IDISPOSABLE,太多了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM