信息管理系统网站开发教程江苏省建设招标网站
信息管理系统网站开发教程,江苏省建设招标网站,自建网站需要什么手续,免费做国际贸易的网站场景是这样#xff0c;假设有一台设备会触发类型为Alarm的告警信号#xff0c;并把信号添加到一个Queue结构中#xff0c;每隔一段时间这个Queue会被遍历检查#xff0c;其中的每个Alarm都会调用一个相应的处理方法。问题在于#xff0c;检查机制是基于多线程的#xff0… 场景是这样假设有一台设备会触发类型为Alarm的告警信号并把信号添加到一个Queue结构中每隔一段时间这个Queue会被遍历检查其中的每个Alarm都会调用一个相应的处理方法。问题在于检查机制是基于多线程的有潜在的并发可能当某个Alarm被添加的同时刚好又在遍历Queue就会抛出异常说Queue发生改变。产生问题的代码如下public class AlarmQueueManager{ public ConcurrentQueueAlarm alarmQueue new ConcurrentQueueAlarm(); System.Timers.Timer timer; public AlarmQueueManager() { timer new System.Timers.Timer(1000); timer.Elapsed new System.Timers.ElapsedEventHandler(timer_Elapsed); timer.Enabled true; } void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { DeQueueAlarm(); } private void DeQueueAlarm() { try { foreach (Alarm alarm in alarmQueue) { SendAlarm(alarm); alarmQueue.TryDequeue(); //having some trouble here with TryDequeue.. } } catch { } }}那么如何让DeQueueAlarm保证线程安全呢 为了简化描述用以下两种写法来对比介绍。// 写法一private void DeQueueAlarm(){ Alarm alarm; while (alarmQueue.TryDequeue(out alarm)) SendAlarm(alarm);} // 写法二private void DeQueueAlarm(){ foreach (Alarm alarm in alarmQueue) SendAlarm(alarm);}参考MSDN的说法ConcurrentQueueT.GetEnumerator 。The enumeration represents a moment-in-time snapshot of the contents of the queue. It does not reflect any updates to the collection after GetEnumerator was called. The enumerator is safe to use concurrently with reads from and writes to the queue.所以两种写法在多线程并发访问的差别就是使用TryQueue会确保每个Alarm只会被处理一次但哪个线程处理哪个Alarm是不确定的。使用foreach循环会确保参与争用的所有线程都同等无差别地访问Queue的全部Alarm就像Queue被重复处理了n遍。因此如果想要严格控制每个Alarm只会被处理一次用完就移除的话那就使用第一种写法。原文地址 http://www.cnblogs.com/BeanHsiang/p/8733059.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/86350.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!