Nyra
Nyra

Reputation: 897

locking messing up serialport handles

I have a question on concept design using system.timers, and threading.

consider the following pseudo code (it is in C# but as I'm asking conceptual, I am not checking syntax for accuracy)

class exam{
    private Serialport sp;
    private readonly object lckObj = new object();
    System.Timer timer;

    public exam()
    {
        // actually I think this lock is not needed as
        // the object gets created on thread creation... 
        // a yay-nay on this would be cool too, I figure it
        // can't hurt to lock
        lock(lckObj) 
        {
            // do stuff
            sp = new Serialport(params);
            sp.DataRecieved += sp_dataRec;

            timer = new system.Timer(someNumber);
            timer.Elapsed += timeElap;
            timer.Enabled = true;
            // also from my understanding in how enabled 
            // works, this is redundant and I can remove
            timer.Start(); 
        }
    }

    private void timeElap()
    {
        lock(lckObj)
        {
            if(sp.Closed) sp.Open();
        }
    }

    private void sp_dataRec()
    {
        lock(lckObj)
        {            
           //do stuff to process message
           // set success bool
           bool success = outcomeOfProcessing;
           callResponse(success);
        }
    }

    private void callResponse(bool success)
    {   
        if(!sp.IsOpen) sp.Open();

        // logic to assemble response hinged on success
        sp.Write("something");
    }
}

What I am trying to do is have the timer come through and check every few seconds to make sure the port ins't closed. This has come about because "something" no clue what is closing the port- found this by attaching a port monitor and it just pops closed at random. No errors pop or anything (no timer suppression errors, I'm looking to add timer). No clue why this is happening (also never in code am I .Close(); ing the port)

However as I am thinking this trough I am now concerned that if I lock to check on the serialport to check state, as well as locking on it to send message back- will this inhibit my data received handle, or will it still queue accordingly

For example I lock on the serial port to check state, and just slightly after enough to miss maybe on byte my data in pops and instead of getting

.1234.

I get

1234.

Note the dot's being start/stop bytes

Edit: I forgot to mention my other concern is the Sytem.Timer suppressing errors of serialport interference

Edit2: I removed the lock from the callResponse- as I am looking at it again calls to the response would be withing the already locked method- so it should be thread-safe still- Correct?

Upvotes: 1

Views: 764

Answers (1)

Jim Mischel
Jim Mischel

Reputation: 133995

The SerialPort buffers data. By the time your received event handler is called, the underlying control has already read the data from the serial port and stored it in an internal buffer. The lock will not cause a problem unless you hold it so long that the data buffer fills up.

That said, I must repeat what I said in comments: your proposed solution can't be made to work reliably. If something external to your program is disabling the serial port asynchronously, it can happen at any time regardless of the state your program is in. You have a one-second timer that checks to see if the port is closed and, if so, re-opens it. That might solve the problem "most of the time," but there's no guarantee that the port won't be closed immediately after you re-open it, or it could be closed while your program is in the middle of sending or receiving data. Remember: your code doesn't do the actual send or receive, but rather reads from or writes to a buffer that is managed by the underlying SerialPort control.

You really need to find out what is causing the serial port to be closed, and prevent that from happening. That's the only way to make your program reliable.

Upvotes: 3

Related Questions