简体   繁体   中英

c# serial port receive event: program is still branching the receive event when i close the port and delete event from Port.DataReceived

I want to disable/enable the receive without closing the port or deleting the receive handler method because they are not working or i'm doing wrong something.

I'm doing now;

byte[] rData = new byte[10];
public void SendData(byte[] a, int count)
{
    if (Port.IsOpen == false)
        Port.Open();
    Port.Write(a, 0, count);
    // start receive timeout timer
    Port.DataReceived += new SerialDataReceivedEventHandler(ReceiveData);
}
public void ReceiveData(object s, SerialDataReceivedEventArgs e)
{
    int ctrl = 0;
    int DataCnt = 5; // for example
    Port = (SerialPort)s;
    ctrl = Port.Read(rData, 0, DataCnt); // if timeout haven't finished yet
    if (ctrl != DataCnt)
    { /* set receive error flag */ }
    else
    {
        Port.DiscardInBuffer();
        if (Port.IsOpen == true)
            Port.Close();
        Port.DataReceived -= new SerialDataReceivedEventHandler(ReceiveData);
        // set receive complete flag
    }
}

I'm getting the bytes correctly but when the program branches the else block of the ReceiveData , I'm discarding input buffer, closing the port if it is open, and deleting the receive event hander but it's again branching in the ReceiveData and naturally InvalidOperationException event is occuring because I've closed the port. Why the program is branching again the receive event after delete the event from Port.DataReceived ? I'm using Windows 8.1 pro and visual studio 2010 pro. Thank you.

my advice would be to not mess about with the port inside your data received event handler. You don't know what the port does after calling your handler (or what other event handlers subscribed to the same event might do) and it may not expect to be closed when you return, which could cause "undefined behavior"

Instead, set a flag to indicate that you have received all the data and are ready to close the port, and get your main program loop to actually close it at some point in the future. (you can also ignore any extra calls to your data received event handler once you have the information you need)

After unsubscribing an event handler you can still get calls to your handler if another thread was in the process of calling the handlers at the moment you unsubscribed. So to avoid race conditions it is better to handle additional calls gracefully than rely on unsubscribing during event handling. This is unlikely, but where threading is concerned, "unlikely" usually happens quite often!

A good rule of thumb to remember for event handlers is to do as little work as possible while you are handling the event. Record what you need to know and defer all other processing to another thread so you can return quickly to the caller.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM