科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件Visual C#中使用线程

Visual C#中使用线程

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文论述了各种模式的线程(单线程、单元线程和自由线程)以及每种模式的使用方法......

作者:佚名 来源:Microsoft 2007年11月14日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
示例应用程序

  第一步是要检查示例应用程序的设计。应用程序将生成多个线程,每个线程都侦听来自 MSMQ 队列的消息。本示例使用两个类,主 Form 类和自定义 MQListen 类。Form 类将处理用户界面并创建,管理和破坏辅助线程。MQListen 类包含所有代码,包括辅助线程运行所需的消息队列因素。

  准备应用程序
  • 要启动应用程序,请打开 Visual Studio .NET 并创建一个名为 MultiThreadedMQListener 的新 C# Windows 应用程序。打开窗体的属性,将其命名为 QueueListenerForm。画出初始窗体后,将两个标签、两个按钮、一个状态栏和两个文本框拖放到窗体上。将第一个文本框命名为 Server,第二个文本框命名为 Queue。将第一个按钮命名为 StartListening,第二个按钮命名为 StopListening。可以保留状态栏的默认名称 statusBar1
  • 下一步,单击 Project(项目)菜单并单击 Add Reference(添加引用),以向 System.Messaging 名称空间添加一个引用。在 .NET 组件列表中找到并选择 System.Messaging.Dll。名称空间包含与 MSMQ 队列通信所使用的类。
  • 下一步,单击 File(文件)菜单,然后单击 Add New Item(添加新项),以在项目中添加一个新类。选择 Class(类)模板并将其命名为 MQListen。在类的顶部添加下列 using 语句:

    // C#
    using System.Threading;
    using System.Messaging;

    System.Threading 名称空间允许您访问所有必要的线程功能,在本例中,您可以访问 Thread 类和 ThreadInterruptException 构造函数。该名称空间还包括许多其他高级功能,本文不作详细讨论。System.Messaging 名称空间允许您访问 MSMQ 功能,包括向队列发送消息和接收队列消息。在本例中,您将使用 MessageQueue 类来接收消息。还必须在主窗体代码中添加 using System.Threading。

  所有引用就位后,您就可以开始编写代码了。

  辅助线程

  首先需要构建封装所有线程工作的 MQListen 类。将下列代码插入 MQListen 中。

// C#
public class MQListen
{
private string m_MachineName;
private string m_QueueName;

// 构造函数接收必要的队列信息。
public MQListen(string MachineName, string QueueName)
{
m_MachineName = MachineName;
m_QueueName = QueueName;
}

// 每个线程用来侦听 MQ 消息的一种唯一方法
public void Listen()
{
// 创建一个 MessageQueue 对象。
System.Messaging.MessageQueue MQ = new
System.Messaging.MessageQueue();

// 设置 MessageQueue 对象的路径属性。
MQ.Path = m_MachineName + "\\private$\\" + m_QueueName;

// 创建一个 Message 对象。
System.Messaging.Message Message = new
System.Messaging.Message();
// 重复上述步骤,直到收到中断。
while (true)
{
try
{
// 休眠以在中断发出时捕捉中断。
System.Threading.Thread.Sleep(100);
// 将 Message 对象设置为与接收函数的结果相等。
// 持续时间(天、小时、分钟、秒)。
Message = MQ.Receive(new TimeSpan(0, 0, 0, 1));

// 显示已接收消息的标签
System.Windows.Forms.MessageBox.Show(" Label: " + Message.Label);

}
catch (ThreadInterruptedException e)
{
// 从主线程捕捉 ThreadInterrupt 并退出。
Console.WriteLine("Exiting Thread");
Message.Dispose();
MQ.Dispose();
break;
}
catch (Exception GenericException)
{
// 捕捉接收过程中抛出的所有异常。
Console.WriteLine(GenericException.Message);
}
}
}
}

  代码讨论

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

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

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

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

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

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

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

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

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章