在多线程之间执行代码

时间:2013-08-27 12:15:11

标签: thread-safety queue task monitor autoresetevent

我正在编写一个需要与串口通信的程序。我主要担心的是防止碰撞并确保不会同时写入/读取不同的功能。

首先,系统计时器从一开始就启动,用于定期将数据写入串口,并通过给定的超时值监听响应。因此,它将有一个Elapsed Event并开展工作。

其次,还有另一个具有更高优先级的功能,需要立即将数据写入串口。

情景1。 经过的事件每1分钟触发一次,如果仍然从前一个或SendImmediately函数挂起,则永远不会继续。

情景2。 如果正在调用SendImmediate,则需要等待当前运行的OnTimedEvent完成。同样,OnTimedEvent的下一次运行将停止,直到SendImmediately完成。

问题。 如何在上一个或SendImmediately完成之前阻止下一次运行OnTimedEvent?基本上,为了防止它们之间的干扰。

我在这里经历了一些Q& A.有许多建议的答案如下:

  • 禁用并启用计时器
  • AutoResetEvent(双向信令)
  • ManualResetEvent的
  • Monitor.Enter / Monitor.Exit(锁定)
  • 队列
  • 睡眠/加入/任务。等待(阻止)

我没有坚实的基础来确定哪一种对我来说是正确的或合适的方法,因为每种方法都有不同的情景。非常感谢任何建议。

    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
    }

1 个答案:

答案 0 :(得分:0)

我会通过让一个'SerialComms'线程在生产者 - 消费者队列上等待超时来实现。如果队列等待超时,则SerialComms执行轮询定时操作,然后返回队列等待。如果优先级较高的thred想要向端口写入内容,它可以对其消息进行排队,因此导致SerialComms队列等待“立即”返回而没有超时,然后“SerialComms”代码可以执行缓冲区的写入。 / p>

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.