Visual C#中使用线程之四(转)

代码讨论

  MQListen 类包含一个不同于构造函数的函数。该函数封装每个辅助线程要执行的所有工作。在主线程中,您向线程构造函数传递一个对此函数的引用,以便在启动线程时执行该函数。

  Listen 所做的第一件事情是设置一个消息队列对象。 MessageQueue 构造函数通过三种实现进行重载。第一种实现使用两个参数:一个字符串参数,指定侦听队列的位置;一个布尔值参数,指示是否为访问队列的第一个应用程序赋予独占读取队列的权限。第二种实现只使用队列路径参数,第三种实现不使用参数。为了简便起见,您可以使用第三种实现,在下一行分配路径。

  如果您引用了队列,则必须创建一个消息对象。消息构造函数也有三种实现方式。如果您想将消息写入队列,则可以使用前两种实现。这两种实现采用两个对象:一个是位于消息正文中的对象;一个是定义如何将对象序列化到消息正文的 IMessageFormatter 对象。在本例中,您将从队列中读取数据,以初始化空的消息对象。

  初始化对象后,您需要输入执行所有工作的主循环。然后,当主线程调用 Interrupt 终止这些线程时,则只有在线程处于等待、睡眠或连接状态下才会被中断。如果没有处于上述三种状态,则要等到下次进入这三种状态中的一种时才会被中断。要确保辅助线程进入等待、睡眠或连接状态,请调用位于 System.Threading 名称空间的 Sleep 方法。对于使用过 Windows API 睡眠函数的 C++ 和 Visual Basic 开发人员而言, Sleep 方法并不陌生。它只使用一个参数:线程处于睡眠状态的毫秒数。如果您从未调用过 Sleep ,辅助线程将永远不会进入可以接收中断请求的状态,而会无限制地继续下去,除非您手动关闭进程。

  MQ Receive 方法有两种实现。第一种实现不使用参数,将一直等待接收消息。第二种实现(本例使用这种实现)使用 TimeSpan 对象指定一个超时值。 TimeSpan 构造函数包含四个参数:日、小时、分钟和秒。在本例中, Receive 方法在超时和返回前将等待一秒种。

  收到的消息将被分配给先前创建的消息对象,然后,便可以对其进行处理了。本例打开一个带有标签的消息框,并删除了此消息。如果您想在实际使用中采用此代码,则可以在此处放置任何消息处理代码。

  当辅助线程收到 Interrupt 请求后,将发出一个 ThreadInterruptedException 异常。要捕捉此异常,请在 try-catch 块中包含 Sleep Receive 函数。您应当指定两个捕获:第一个用于捕获中断异常,第二个用于处理捕获到的错误异常。捕获到中断异常时,请首先将其写入线程正在退出的调试窗口。下一步,对队列对象和消息对象调用 Dispose 方法,以保证所有内存都被清空并发送到内存回收器。最后,中断 while 循环。

  函数退出 while 循环后,关联的线程也将立即结束,代码为 0。在调试窗口,您将看到一则消息,例如“The thread (0x660) has exited with code 0 (0x0)”(线程 (0x660) 已经退出,代码为 0 (0x0))。现在,线程已经退出该环境,并已自动被破坏。主线程和辅助线程都不需要执行专门的清除操作。
  主窗体

  下一步是向窗体添加代码以生成辅助线程并针对各辅助线程启动 MQListen 类。首先,请向窗体添加下列函数:

// C#
private void StartThreads()
{
int LoopCounter; // 线程计数
StopListeningFlag = false; // 跟踪辅助线程是否应当
// 终止的标志。

// 将一个包含 5 个线程的数组声明为辅助线程。
Thread[] ThreadArray = new Thread[5];

// 声明包含辅助线程的所有代码的类。
MQListen objMQListen = new
MQListen(this.ServerName.Text,this.QueueName.Text);

for (LoopCounter = 0; LoopCounter < NUMBER_THREADS; LoopCounter++)
{
// 创建一个 Thread 对象。
ThreadArray[LoopCounter] = new Thread(new
ThreadStart(objMQListen.Listen));
// 启动线程将调用 ThreadStart 委托。
ThreadArray[LoopCounter].Start();
}

statusBar1.Text = LoopCounter.ToString() + " listener threads started";

while (!StopListeningFlag)
{
// 等待用户按下停止按钮。
// 在等待过程中,让系统处理其他事件。
System.Windows.Forms.Application.DoEvents();
}

statusBar1.Text = "Stop request received, stopping threads";
// 向每个线程发送一个中断请求。
for (LoopCounter = 0;LoopCounter < NUMBER_THREADS; LoopCounter++)
{
ThreadArray[LoopCounter].Interrupt();
}

statusBar1.Text = "All Threads have been stopped";
}

[@more@]

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/79548/viewspace-926571/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/79548/viewspace-926571/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值