Question

I am writing a program which need to communicate with the serial port. My major concern will be to prevent collision and ensure no concurrently writing / reading from different functions.

Firstly, there is a system timer started from beginning and used to periodically write data to serial port and also listening to the response by given timeout value. Thus, it will have an Elapsed Event and do the work.

Secondly, there is another function served with higher priority and will need to write data to serial port immediately.

Scenario 1. Elapsed event fired each 1 minutes and never proceed if still pending from previous one or SendImmediately function.

Scenario 2. If SendImmediately being called, it will need to wait for the current running OnTimedEvent finish. Again, the next running of OnTimedEvent will stopped until SendImmediately completed.

Question. How do I prevent the next running of OnTimedEvent before the previous one or SendImmediately finish? Basically, to prevent interference between each of them.

I have went through some Q&A here. There are many suggested answers like below:

  • Disable and Enable timer
  • AutoResetEvent (2 way signaling)
  • ManualResetEvent
  • Monitor.Enter / Monitor.Exit (Locking)
  • Queue
  • Sleep / Join / Task.Wait (Blocking)

I have no solid foundation to determine which one is the right or suitable approach for me since each of them came with different scenarios. Much appreciate for any advice.

    public System.Timers.Timer aTimer = new System.Timers.Timer(Properties.Settings.Default.Interval * 60 * 1000);
    public bool InitialTimer(int interval, bool action)
    {
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = interval;
        aTimer.Enabled = action; 
        GC.KeepAlive(aTimer);
        return action;
    }

    public void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        // write something to serial port
    }
    public void WriteImmediately()
    {
        // write something to serial port
    }
Was it helpful?

Solution

I would do it by having one 'SerialComms' thread waiting on a producer-consumer queue with a timeout. If the queue wait times out, SerialComms performs the polling timed operation and then return to the queue wait. If the higher-priority thred wants to write something to the port, it can queue its message, so causing the SerialComms queue wait to return 'immediately' without a timeout and the 'SerialComms' code can then perform the write of the buffer.

The high-priority writes are signaled onto the SerialComms thread 'immediately'.
No explicit timer required.
No possibility of the high-priority write interrupting an ongoing timed operation.
No possibility of multiple timed operations stacking up or interrupting each other.
Multiple high-priority writes can be queued up without any interference.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top