技巧
下图展示了VS.NET在调试模式时运行这个多线程监听应用的情形。要注意的是下拉的窗口显示了每个线程的名字。选择线程后,代码窗口就会移动到该线程正在执行的地方。要注意的是一个线程的名字只可以设置一次。因此,当工作项目使用同一个线程时,如果设置了Name属性,代码就会抛出一个例外。

QueueListener是真正由多个线程上取回MSMQ队列的类,它还包含有一个构造器,该构造器接收机器名字,并且以队列的形式将名字送至监视器。public Listen方法由队列中接收信息,而public Monitor方法初始化处理并且创建线程池。private ProcessMsg方法则是用来处理接收信息的。最后是public Finish方法,它可以接收一个超时参数,可让QueueListener类使用的线程在一个指定的时间内完成工作。
首先,要注意到Listen方法接收一个状态对象作为参数。该对象将包含有一个EventState的实例,该实例将被Listen用来检查该方法是否正在处理信息还是已经完成处理。通过这样做可确保Finish方法阻塞直到所有的线程完成它们当前的处理。在设置ThreadPriority和Name,以及接收EventState后,你将会注意到该方法仅包含有一个放在Try块中的While循环。该循环反复调用MessageQueue类的Receive方法,方法将返回在指定的超时时间内的第一个得到的信息。如果没有信息,在返回前,就会使用一个TimeSpan对象来通知Receive方法阻塞一秒。如果没有信息接收,将会抛出一个MessageQueueException对象。要注意的是如果有信息到达,该方法将会继续运行并调用Reset方法,Reset方法属于EventState对象内的ResetEvent字段。无论是哪种情况,Finally块都会调用ResetEvent字段的Set方法,表示线程已经完成这个循环处理。
前面已经提及,EventState的ResetEvent字段包含有一个ManualResetEvent的实例,该实例是一个事件对象,它的signaled和non-signaled状态都是可以通过Reset和Set方法手工修改的。在调用Reset方法时,状态就会变为non-signaled,它表明该线程正忙。当状态通过Set事件设置为signaled时,则表明该线程已经完成处理,因此可以安全地破坏。
上一页 [1] [2] [3] [4] [5] [6] [7] 下一页