现在的位置: 首页 > 综合 > 正文

AutoResetEvent abc

2012年03月31日 ⁄ 综合 ⁄ 共 1695字 ⁄ 字号 评论关闭
习惯在了在C++中肆意PostThreadMessage,到了.net下有些乱了方寸。还好有event,不过千万不要和c#中的那个event搞在一起

    // 线程间传送消息
    class Program {
        
static AutoResetEvent autoEvent = new AutoResetEvent(false);
        
static Queue<string> messageQueue = new Queue<string>();

        static void Main(string[] args) {
            
new Thread(new ThreadStart(messageLoop)).Start();
            
new Thread(new ThreadStart(threadProc)).Start();
        }

        static void messageLoop() {
            Queue
<string> transferQueue = new Queue<string>();
        
            
while (autoEvent.WaitOne()) {            
                
// 尽可能的减少messageQueue被锁住的时间
                foreach(string msg in messageQueue) {
                    transferQueue.Enqueue(msg);
                }
                messageQueue.Clear();

                foreach (string msg in transferQueue) {
                    Console.WriteLine(msg);
                }
                transferQueue.Clear();
            } 
// while
        }

        static void threadProc() {
            
// 可以想象这里是网络的接收线程,客户端在源源不断的向这里发送数据

            
lock (messageQueue) { messageQueue.Enqueue("Hello Wolrd!"); }
            autoEvent.Set();

            lock (messageQueue) { messageQueue.Enqueue("today is a good day"); }
            autoEvent.Set();

            lock (messageQueue) { messageQueue.Enqueue("let it be"); }
            autoEvent.Set();
        }
    }

这里的event相当于是一个dirty flag,只要messageQueue加入了message就使这个event激活了,脏一次也是脏,脏两次也是脏
呵呵

这里再简单补充一下event的基本概念,主要参考Win32多线程程序设计

event有两种状态分别是:
激发和未激发
其实就是0,1

有两种使用模式:
手动和自动

手动是指再激发后不会自动重置,必须靠程序操作(调用ResetEvent())才能将其从激发状态设为非激发状态
而自动则表示这个event将在变成激发状态(因而唤醒一个线程)之后,自动重置(reset)为非激发状态

SetEvent: 设为激发状态,Set N次也是激发状态
ResetEvent: 设为非激发状态

从上面的代码可以看到xxxevent.WaitOne就会将event从激发态变为非激发态。

抱歉!评论已关闭.