• 消息队列


     

      在这个数组内部,CWorker 类创建了 CWorkerThread类的一个实现版
    本。CWorkerThread 类(将在下面讨论)是一个必须继承的抽象类。导出
    类定义了消息的处理方式:
    aThreads = new ArrayList();
    for (int idx=0; idx〈sfWorker.NumberThreads; idx++)
    {
      WorkerThreadFormatter wfThread = new WorkerThreadFormatter();
      wfThread.ProcessName = sfWorker.ProcessName;
      wfThread.ProcessDesc = sfWorker.ProcessDesc;
      wfThread.ThreadNumber = idx;
      wfThread.InputQueue = sfWorker.InputQueue;
      wfThread.ErrorQueue = sfWorker.ErrorQueue;
      wfThread.OutputName = sfWorker.OutputName;
      // 定义辅助类型,并将其插入辅助线程结构
      CWorkerThread wtBase;
      switch (sfWorker.ProcessType)
      {
       case WorkerFormatter.SFProcessType.ProcessRoundRobin:
         wtBase = new CWorkerThreadRoundRobin(this, wfThread);
         break;
       case WorkerFormatter.SFProcessType.ProcessAppSpecific:
         wtBase = new CWorkerThreadAppSpecific(this, wfThread);
         break;
       case WorkerFormatter.SFProcessType.ProcessAssembly:
         wtBase = new CWorkerThreadAssembly(this, wfThread);
         break;
       default:
         throw new Exception("Unknown Processing Type");
      }
      // 添加对数组的调用
      aThreads.Insert(idx, wtBase);
    }

      一旦所有的对象都已创建,就可以通过调用每个线程对象的 Start方
    法来启动它们:
    foreach(CWorkerThread cThread in aThreads)
      cThread.Start();

      Stop、Pause 和 Continue 方法在 foreach循环里执行的操作类似。
    Stop方法具有如下的垃圾收集操作:
    GC.SuppressFinalize(this);

      在类析构函数中将调用 Stop 方法,这样,在没有显式调用 Stop 方
    法的情况下也可以正确地终止对象。如果调用了 Stop 方法,将不需要析
    构函数。SuppressFinalize方法能够防止调用对象的 Finalize 方法(析
    构函数的实际实现)。

    CWorkerThread 抽象类

      CWorkerThread 是一个由 CWorkerThreadAppSpecifc、CWorkerThread
    RoundRobin 和 CWorkerThreadAssembly继承的抽象类。无论如何处理消
    息,队列的大部分处理是相同的,所以 CWorkerThread类提供了这一功能。
    这个类提供了抽象方法(必须被实际方法替代)以管理资源和处理消息。

      类的工作再一次通过 Start、Stop、Pause 和 Continue 方法来实现。
    在 Start方法中引用了输入和错误队列。在 .NET 框架中,消息由 System.
    Messaging 名称空间处理:
    // 尝试打开队列,并设置默认的读写属性
    MessageQueue mqInput = new MessageQueue(sInputQueue);
    mqInput.MessageReadPropertyFilter.Body = true;
    mqInput.MessageReadPropertyFilter.AppSpecific = true;
    MessageQueue mqError = new MessageQueue(sErrorQueue);
    // 如果使用 MSMQ COM,则将格式化程序设置为 ActiveX
    mqInput.Formatter = new ActiveXMessageFormatter();
    mqError.Formatter = new ActiveXMessageFormatter();

      一旦定义了消息队列引用,即会创建一个线程用于实际的处理函数
    (称为 ProcessMessages)。在 .NET 框架中,使用 System.Threading
    名称空间很容易实现线程处理:
    procMessage = new Thread(new ThreadStart(ProcessMessages));
    procMessage.Start();

      ProcessMessages 函数是基于 Boolean值的处理循环。当数值设为
    False,处理循环将终止。因此,线程对象的 Stop 方法只设置这一Boolean
    值,然后关闭打开的消息队列,并加入带有主线程的线程:
    // 加入服务线程和处理线程
    bRun = false;
    procMessage.Join();
    // 关闭打开的消息队列
    mqInput.Close();
    mqError.Close();

    Pause 方法只设置一个 Boolean 值,使处理线程休眠半秒钟:

    if (bPause)
      Thread.Sleep(500);

      最后,每一个 Start、Stop、Pause 和 Continue 方法将调用抽象的
    OnStart 、OnStop、OnPause 和 OnContinue 方法。这些抽象方法为实现
    的类提供了挂钩,以捕获和释放所需的资源。

      ProcessMessages 循环具有如下基本结构:
    ●接收Message。
    ●如果Message具有成功的Receive,则调用抽象ProcessMessage方法。
    ●如果Receive或ProcessMessage失败,将Message发送至错误队列中。

    Message mInput;
    try
    {
      // 从队列中读取,并等候 1 秒
      mInput = mqInput.Receive(new TimeSpan(0,0,0,1));
    }
    catch (MessageQueueException mqe)
    {
      // 将消息设置为 null
      mInput = null;
      // 查看错误代码,了解是否超时
      if (mqe.ErrorCode != (-1072824293) ) //0xC00E001B
      {
       // 如果未超时,发出一个错误并记录错误号
       LogError("Error: " + mqe.Message);
       throw mqe;
      }
    }
    if (mInput != null)
    {
      // 得到一个要处理的消息,调用处理消息抽象方法
      try
      {
       ProcessMessage(mInput);
      }
      // 捕获已知异常状态的错误
      catch (CWorkerThreadException ex)
      {
       ProcessError(mInput, ex.Terminate);
      }
      // 捕获未知异常,并调用 Terminate
      catch
      {
       ProcessError(mInput, true);
      }
    }

      ProcessError方法将错误的消息发送至错误队列。另外,它也可能引
    发异常来终止线程。如果ProcessMessage方法引发了终止错误或 CWorker
    ThreadException类型,它将执行此操作。

    CworkerThread 导出类

      任何从 CWorkerThread中继承的类都必须提供 OnStart、OnStop、On
    Pause、OnContinue和 ProcessMessage 方法。OnStart 和 OnStop方法获
    取并释放处理资源。OnPause 和 OnContinue 方法允许临时释放和重新获
    取这些资源。ProcessMessage方法应该处理消息,并在出现失败事件时引
    发 CWorkerThreadException 异常。

      由于 CWorkerThread构造函数定义运行时参数,导出类必须调用基类
    构造函数:
    public CWorkerThreadDerived(CWorker v_cParent, WorkerThread
    Formatter v_wfThread)
      : base (v_cParent, v_wfThread) {}

      导出类提供了两种类型的处理:将消息发送至另一队列,或者调用组
    件方法。接收和发送消息的两种实现使用了循环技术或应用程序偏移(保
    留在消息 AppSpecific属性中),作为使用哪一队列的决定因素。此方案
    中的配置文件应该包括队列路径的列表。实现的 OnStart和 OnStop 方法
    应该打开和关闭对这些队列的引用:
    iQueues = wfThread.OutputName.Length;
    mqOutput = new MessageQueue[iQueues];
    for (int idx=0; idx〈iQueues; idx++)
    {
      mqOutput[idx] = new MessageQueue(wfThread.OutputName[idx]);
      mqOutput[idx].Formatter = new ActiveXMessageFormatter();
    }

      在这些方案中,消息的处理很简单:将消息发送必要的输出队列。在
    循环情况下,这个进程为:
    try
    {
      mqOutput[iNextQueue].Send(v_mInput);
    }
    catch (Exception ex)
    {
      // 如果错误强制终止异常
      throw new CWorkerThreadException(ex.Message, true);
    }
    // 计算下一个队列号
    iNextQueue++;
    iNextQueue %= iQueues;

      后一种调用带消息参数的组件的实现方法比较有趣。ProcessMessage
    方法使用 IWebMessage接口调入一个 .NET 组件。OnStart 和 OnStop 方
    法获取和释放此组件的引用。

      此方案中的配置文件应该包含两个项目:完整的类名和类所在文件的
    位置。按照 IWebMessage接口中的定义,在组件上调用 Process方法。

      要获取对象引用,需要使用 Activator.CreateInstance 方法。此函
    数需要一个程序集类型。在这里,它是从程序集文件路径和类名中导出的。
    一旦获取对象引用,它将被放入合适的接口:
    private IWebMessage iwmSample;
    private string sFilePath, sTypeName;
    // 保存程序集路径和类型名称
    sFilePath = wfThread.OutputName[0];
    sTypeName = wfThread.OutputName[1];
    // 获取对必要对象的引用
    Assembly asmSample = Assembly.LoadFrom(sFilePath);
    Type

    typSample = asmSample.GetType(sTypeName);
    object objSample = Activator.CreateInstance(typSample);
    // 定义给对象的必要接口
    iwmSample = (IWebMessage)objSample;

      获取对象引用后,ProcessMessage方法将在 IWebMessage接口上调用
    Process 方法:
    WebMessageReturn wbrSample;
    try
    {
      // 定义方法调用的参数
      string sLabel = v_mInput.Label;
      string sBody = (string)v_mInput.Body;
      int iAppSpecific = v_mInput.AppSpecific;
      // 调用方法并捕捉返回代码
      wbrSample = iwmSample.Process(sLabel, sBody, iAppSpecific);
    }
    catch (InvalidCastException ex)
    {
      // 如果在消息内容中发生错误,则强制发出一个非终止异常
      throw new CWorkerThreadException(ex.Message, false);
    }
    catch (Exception ex)
    {
      // 如果错误调用程序集,则强制发出终止异常
      throw new CWorkerThreadException(ex.Message, true);
    }
    // 如果没有错误,则检查对象调用的返回状态
    switch (wbrSample)
    {
      case WebMessageReturn.ReturnBad:
       throw new CWorkerThreadException
         ("Unable to process message: Message marked bad", false);
      case WebMessageReturn.ReturnAbort:
       throw new CWorkerThreadException
         ("Unable to process message: Process terminating", true);
      default:
       break;
    }

      提供的示例组件将消息正文写入数据库表。如果捕获到严重数据库错
    误,您可能希望终止处理过程,但是在这里,仅仅将消息标记为错误的消
    息。

      由于此示例中创建的类实例可能会获取并保留昂贵的数据库资源,所
    以用 OnPause和 OnContinue 方法释放和重新获取对象引用。

    检测设备

      就象在所有优秀的应用程序中一样,检测设备用于监测应用程序的状
    态。。NET 框架大大简化了将事件日志、性能计数器和 Windows管理检测
    设备(WMI )纳入应用程序的过程。消息应用程序使用时间日志和性能计
    数器,二者都是来自 System.Diagnostics 程序集。

      在 ServiceBase类中,您可以自动启用事件日志。另外,ServiceBase
    EventLog成员支持写入应用程序事件日志:
    EventLog.WriteEntry(sMyMessage, EventLogEntryType.Information);

      对于写入事件日志而不是应用程序日志的应用程序,它能够很容易地
    创建和获取 EventLog 资源的引用(正如在 CWorker类中所做的一样),
    并能够使用 WriteEntry 方法记录日志项:
    private EventLog cLog;
    string sSource = ServiceControl.ServiceControlName;
    string sLog = "Application";
    // 查看源是否存在,如果不存在,则创建源
    if (!EventLog.SourceExists(sSource))
      EventLog.Creat

    eEventSource(sSource, sLog);
    // 创建日志对象,并引用现在定义的源
    cLog = new EventLog();
    cLog.Source = sSource;
    // 在日志中写入条目,表明创建成功
    cLog.WriteEntry("已成功创建", EventLogEntryType.Information);

      .NET 框架大大简化了性能计数器。对于每一个处理线程、线程导出
    的用户和整个应用程序,这一消息应用程序都能提供计数器,用于跟踪消
    息数量和每秒钟处理消息的数量。要提供此功能,您需要定义性能计数器
    的类别,然后增加相应的计数器实例。

      性能计数器的类别在服务 OnStart方法中定义。这些类别代表两种计
    数器——消息总数和每秒钟处理的消息数:
    CounterCreationData[] cdMessage = new CounterCreationData[2];
    cdMessage[0] = new CounterCreationData("Messages/Total", "Total
    Messages Processed",
    PerformanceCounterType.NumberOfItems64);
    cdMessage[1] = new CounterCreationData("Messages/Second",
    "Messages Processed a Second",
    PerformanceCounterType.RateOfChangePerSecond32);
    PerformanceCounterCategory.Create("MSDN Message Service", "MSDN
    Message Service Counters", cdMessage);

      一旦定义了性能计数器类别,将创建 PerformanceCounter 对象以访
    问计数器实例功能。PerformanceCounter对象需要类别、计数器名称和一
    个可选的实例名称。对于辅助进程,将使用来自 XML文件的进程名称,代
    码如下:
    pcMsgTotWorker = new PerformanceCounter("MSDN Message Service",
    "Messages/Total", sProcessName);
    pcMsgSecWorker = new PerformanceCounter("MSDN Message Service",
    "Messages/Second", sProcessName);
    pcMsgTotWorker.RawValue = 0;
    pcMsgSecWorker.RawValue = 0;

    要增加计数器的值,仅仅需要调用适当的方法:

    pcMsgTotWorker.IncrementBy(1);
    pcMsgSecWorker.IncrementBy(1);

    最后说明一点,服务终止时,安装的性能计数器类别应该从系统中删除:

    PerformanceCounterCategory.Delete("MSDN Message Service");

      由于性能计数器在 .NET 框架中工作,因此需要运行一项特殊的服务。
    此服务(PerfCounterService)提供了共享内存。计数器信息将写入共享
    内存,并被性能计数器系统读取。

    安装

      在结束以前,我们来简要介绍一下安装以及称为 installutil.exe的
    安装工具。由于此应用程序是 Windows服务,它必须使用installutil.exe
    来安装。因此,需要使用一个从 System.Configuration.Install 程序集
    中继承的 Installer类:
    public class ServiceRegister: Installer
    {
      private ServiceInstaller serviceInstaller;
      private ServiceProcessInstaller processInstaller;
      public ServiceRegi

    ster()
      {
       // 创建服务安装程序
       serviceInstaller = new ServiceInstaller();
       serviceInstaller.StartType = ServiceStart.Manual;
       serviceInstaller.ServiceName = ServiceControl.ServiceControl
       Name;
       serviceInstaller.DisplayName = ServiceControl.ServiceControl
       Desc;
       Installers.Add(serviceInstaller);
       // 创建进程安装程序
       processInstaller = new ServiceProcessInstaller();
       processInstaller.RunUnderSystemAccount = true;
       Installers.Add(processInstaller);
      }
    }

      如此示例类所示,对于一个 Windows服务,服务和服务进程各需要一
    个安装程序,以定义运行服务的帐户。其他安装程序允许注册事件日志和
    性能计数器等资源。

    总结

      从这个 .NET 框架应用程序示例中可以看出,以前只有 Visual C++
    程序员能够编写的应用程序,现在使用简单的面向对象程序即可实现。尽
    管我们的重点是 C# ,但本文所述的内容也同样适用于 Visual Basic 和
    Managed C++.新的 .NET 框架使开发人员能够使用任何编程语言来创建功
    能强大、可伸缩的 Windows应用程序和服务。

      新的 .NET 框架不仅简化和扩展了编程的种种可能,还能够轻松地将
    人们经常遗忘的应用程序检测设备(例如性能监测计数器和事件日志通知)
    合并到应用程序中。尽管这里的应用程序没有使用 Windows管理检测设备
    (WMI ),但 .NET 框架同样也可以应用它。

    using System;
    using System.Drawing;
    using System.Collections;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Data;
    using System.Messaging ;
    using System.Threading ;

    namespace WinMsmq
    {
     /// <summary>
     /// Form1 的摘要说明。
     /// </summary>
     public class Form1 : System.Windows.Forms.Form
     {
      static ManualResetEvent signal = new ManualResetEvent(false);
      static ManualResetEvent  pubRecvieSignal=new ManualResetEvent(false);
      private System.Messaging.MessageQueue mq=null;
      private readonly  string  qryname=@"";
      private  MessageQueue msq=null;
      private  MessageQueue pubMsq=null;
      private System.Windows.Forms.Button button1;
      private System.Windows.Forms.Button button2;
      private System.Windows.Forms.Button button3;
      private System.Windows.Forms.RichTextBox richTextBox1;
      private System.Windows.Forms.GrouPBox groupBox1;
      private System.Windows.Forms.GroupBox groupBox2;
      private System.Windows.Forms.Button button5;
      private System.Windows.Forms.Button button6;
      private System.Windows.Forms.Button button7;
      private System.Windows.Forms.GroupBox groupBox3;
      private System.Windows.Forms.Button sendToPub;
      private System.Windows.Forms.Button readFromPub;
      private System.Windows.Forms.Button Creaet;
      private System.Windows.Forms.Button button4;
      private System.Windows.Forms.Button delPubmsg;
      private System.Windows.Forms.Button srPub;
      private System.Data.SqlClient.SqlConnection sqlConnection1;
      /// <summary>
      /// 必需的设计器变量。
      /// </summary>
      private System.ComponentModel.Container components = null;
      public Form1()
      {
       //
       // Windows 窗体设计器支持所必需的
       //
       InitializeComponent();
       this.qryname=System.Configuration.ConfigurationSettings.AppSettings["pubMsmqQryName"];
       if(MessageQueue.Exists(qryname))
       {
        this.pubMsq=new MessageQueue(qryname,true);
       }
       else
       {
        this.pubMsq=System.Messaging.MessageQueue.Create(qryname,true);
       }
       this.richTextBox1.AppendText("==================\r\n");
       this.richTextBox1.AppendText(this.pubMsq .QueueName +":公共队列创建成功!\r\n");

       //
       // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
       //
      }
      /// <summary>
      /// 清理所有正在使用的资源
      /// </summary>
      protected override void Dispose( bool disposing )
      {
       if( disposing )
       {
        if (components != null)
        {
         components.Dispose();
        }
       }
       base.Dispose( disposing );
      }

      #region Windows 窗体设计器生成的代码
      /// <summary>
      /// 设计器支持所需的方法 - 不要使用代码编辑器修改
      /// 此方法的内容。
      /// </summary>
      private void InitializeComponent()
      {
       this.button1 = new System.Windows.Forms.Button();
       this.button2 = new System.Windows.Forms.Button();
       this.button3 = new System.Windows.Forms.Button();
       this.richTextBox1 = new System.Windows.Forms.RichTextBox();
       this.groupBox1 = new System.Windows.Forms.GroupBox();
       this.groupBox2 = new System.Windows.Forms.GroupBox();
       this.button4 = new System.Windows.Forms.Button();
       this.button7 = new System.Windows.Forms.Button();
       this.Creaet = new System.Windows.Forms.Button();
       this.button6 = new System.Windows.Forms.Button();
       this.button5 = new System.Windows.Forms.Button();
       this.groupBox3 = new System.Windows.Forms.GroupBox();
       this.srPub = new System.Windows.Forms.Button();
       this.delPubmsg = new System.Windows.Forms.Button();
       this.readFromPub = new System.Windows.Forms.Button();
       this.sendToPub = new System.Windows.Forms.Button();
       this.sqlConnection1 = new System.Data.SqlClient.SqlConnection();
       this.groupBox1.SuspendLayout();
       this.groupBox2.SuspendLayout();
       this.groupBox3.SuspendLayout();
       this.SuspendLayout();
       //
       // button1
       //
       this.button1.Location = new System.Drawing.Point(8, 56);
       this.button1.Name = "button1";
       this.button1.TabIndex = 0;
       this.button1.Text = "SendMsg";
       this.button1.Click += new System.EventHandler(this.button1_Click);
       //
       // button2
       //
       this.button2.Location = new System.Drawing.Point(8, 16);
       this.button2.Name = "button2";
       this.button2.TabIndex = 1;
       this.button2.Text = "CreateMsmq";
       this.button2.Click += new System.EventHandler(this.button2_Click);
       //
       // button3
       //
       this.button3.Location = new System.Drawing.Point(8, 104);
       this.button3.Name = "button3";
       this.button3.TabIndex = 2;
       this.button3.Text = "ReadMsg";
       this.button3.Click += new System.EventHandler(this.button3_Click);
       //
       // richTextBox1
       //
       this.richTextBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
        | System.Windows.Forms.AnchorStyles.Left)
        | System.Windows.Forms.AnchorStyles.Right)));
       this.richTextBox1.Location = new System.Drawing.Point(0, 152);
       this.richTextBox1.Name = "richTextBox1";
       this.richTextBox1.Size = new System.Drawing.Size(640, 188);
       this.richTextBox1.TabIndex = 3;
       this.richTextBox1.Text = "richTextBox1";
       //
       // groupBox1
       //
       this.groupBox1.Controls.Add(this.button2);
       this.groupBox1.Controls.Add(this.button1);
       this.groupBox1.Controls.Add(this.button3);
       this.groupBox1.Location = new System.Drawing.Point(16, 0);
       this.groupBox1.Name = "groupBox1";
       this.groupBox1.Size = new System.Drawing.Size(144, 136);
       this.groupBox1.TabIndex = 4;
       this.groupBox1.TabStop = false;
       this.groupBox1.Text = "非事务";
       //
       // groupBox2
       //
       this.groupBox2.Controls.Add(this.button4);
       this.groupBox2.Controls.Add(this.button7);
       this.groupBox2.Controls.Add(this.Creaet);
       this.groupBox2.Controls.Add(this.button6);
       this.groupBox2.Controls.Add(this.button5);
       this.groupBox2.Location = new System.Drawing.Point(184, 0);
       this.groupBox2.Name = "groupBox2";
       this.groupBox2.Size = new System.Drawing.Size(240, 136);
       this.groupBox2.TabIndex = 5;
       this.groupBox2.TabStop = false;
       this.groupBox2.Text = "事务性";
       //
       // button4
       //
       this.button4.Location = new System.Drawing.Point(168, 80);
       this.button4.Name = "button4";
       this.button4.Size = new System.Drawing.Size(56, 48);
       this.button4.TabIndex = 5;
       this.button4.Text = "CreateMsmqWithTran";
       this.button4.Click += new System.EventHandler(this.button4_Click);
       //
       // button7
       //
       this.button7.Location = new System.Drawing.Point(16, 104);
       this.button7.Name = "button7";
       this.button7.Size = new System.Drawing.Size(136, 23);
       this.button7.TabIndex = 4;
       this.button7.Text = "ClearMsgOfRichTxtBox";
       this.button7.Click += new System.EventHandler(this.button7_Click);
       //
       // Creaet
       //
       this.Creaet.Location = new System.Drawing.Point(144, 32);
       this.Creaet.Name = "Creaet";
       this.Creaet.Size = new System.Drawing.Size(80, 40);
       this.Creaet.TabIndex = 3;
       this.Creaet.Text = "异步读取消息";
       this.Creaet.Click += new System.EventHandler(this.Read);
       //
       // button6
       //
       this.button6.Location = new System.Drawing.Point(16, 72);
       this.button6.Name = "button6";
       this.button6.Size = new System.Drawing.Size(104, 23);
       this.button6.TabIndex = 2;
       this.button6.Text = "ReadMsgTran";
       this.button6.Click += new System.EventHandler(this.button6_Click);
       //
       // button5
       //
       this.button5.Location = new System.Drawing.Point(16, 32);
       this.button5.Name = "button5";
       this.button5.Size = new System.Drawing.Size(104, 24);
       this.button5.TabIndex = 1;
       this.button5.Text = "SendMsgTran";
       this.button5.Click += new System.EventHandler(this.button5_Click);
       //
       // groupBox3
       //
       this.groupBox3.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
        | System.Windows.Forms.AnchorStyles.Right)));
       this.groupBox3.Controls.Add(this.srPub);
       this.groupBox3.Controls.Add(this.delPubmsg);
       this.groupBox3.Controls.Add(this.readFromPub);
       this.groupBox3.Controls.Add(this.sendToPub);
       this.groupBox3.Location = new System.Drawing.Point(432, 0);
       this.groupBox3.Name = "groupBox3";
       this.groupBox3.Size = new System.Drawing.Size(208, 136);
       this.groupBox3.TabIndex = 6;
       this.groupBox3.TabStop = false;
       this.groupBox3.Text = "公共队列";
       //
       // srPub
       //
       this.srPub.Location = new System.Drawing.Point(144, 72);
       this.srPub.Name = "srPub";
       this.srPub.Size = new System.Drawing.Size(56, 48);
       this.srPub.TabIndex = 4;
       this.srPub.Text = "检索公共队列";
       this.srPub.Click += new System.EventHandler(this.srPub_Click);
       //
       // delPubmsg
       //
       this.delPubmsg.Location = new System.Drawing.Point(8, 96);
       this.delPubmsg.Name = "delPubmsg";
       this.delPubmsg.Size = new System.Drawing.Size(112, 24);
       this.delPubmsg.TabIndex = 3;
       this.delPubmsg.Text = "DeletePubMsmg";
       this.delPubmsg.Click += new System.EventHandler(this.delPubmsg_Click);
       //
       // readFromPub
       //
       this.readFromPub.Location = new System.Drawing.Point(8, 64);
       this.readFromPub.Name = "readFromPub";
       this.readFromPub.Size = new System.Drawing.Size(128, 24);
       this.readFromPub.TabIndex = 2;
       this.readFromPub.Text = "ReadMsgFromPubMsmg";
       this.readFromPub.Click += new System.EventHandler(this.readFromPub_Click);
       //
       // sendToPub
       //
       this.sendToPub.Location = new System.Drawing.Point(8, 32);
       this.sendToPub.Name = "sendToPub";
       this.sendToPub.Size = new System.Drawing.Size(144, 24);
       this.sendToPub.TabIndex = 1;
       this.sendToPub.Text = "SendMsgToPubMsmq";
       this.sendToPub.Click += new System.EventHandler(this.sendToPub_Click);
       //
       // sqlConnection1
       //
       this.sqlConnection1.ConnectionString = "workstation id=DHZ;packet size=4096;integrated security=SSPI;data source=\"DHZ\\DHZ" +
        "\";persist security info=False;initial catalog=Northwind";
       //
       // Form1
       //
       this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
       this.ClientSize = new System.Drawing.Size(648, 349);
       this.Controls.Add(this.groupBox3);
       this.Controls.Add(this.groupBox2);
       this.Controls.Add(this.groupBox1);
       this.Controls.Add(this.richTextBox1);
       this.Name = "Form1";
       this.Text = "Form1";
       this.Load += new System.EventHandler(this.Form1_Load);
       this.groupBox1.ResumeLayout(false);
       this.groupBox2.ResumeLayout(false);
       this.groupBox3.ResumeLayout(false);
       this.ResumeLayout(false);

      }
      #endregion

      /// <summary>
      /// 应用程序的主入口点。
      /// </summary>
      [STAThread]
      static void Main()
      {
       Application.Run(new Form1());
      }
      private void Form1_Load(object sender, System.EventArgs e)
      {
       
       if(MessageQueue.Exists(@".\private$\dhzOrderMgmt"))
       {
        this.mq=new MessageQueue(@".\private$\dhzOrderMgmt");
       }
       else
       {
        this.mq=MessageQueue.Create(@".\private$\dhzOrderMgmt",false);
       }
       this.richTextBox1.AppendText("==================\r\n");
       this.richTextBox1.AppendText(mq.QueueName +":创建成功!\r\n");
      
      
      }
      private void button1_Click(object sender, System.EventArgs e)
      {
       Od od=new Od("代汉章","南昌",DateTime.Now.ToLongTimeString ());
       if(this.mq.Transactional)
       {
        this.mq.Send(od,new System.Messaging.MessageQueueTransaction ());
       }
       else
       {
        this.mq.Send(od);
       }
       this.richTextBox1.AppendText("发送成功!\r\n");
      }
      private void button2_Click(object sender, System.EventArgs e)
      {
      
       if(MessageQueue.Exists(@".\private$\dhzOrderMgmt"))
       {
        this.mq=new MessageQueue(@".\private$\dhzOrderMgmt");
       }
       else
       {
        this.mq=MessageQueue.Create(@".\private$\dhzOrderMgmt",false);
       }
       this.richTextBox1.AppendText("==================\r\n");
       this.richTextBox1.AppendText(mq.QueueName +":创建成功!\r\n");
      

      }
      private void button3_Click(object sender, System.EventArgs e)
      {
       if(this.mq!=null)
       {
        System.Messaging.MessageEnumerator  msg=this.mq.GetMessageEnumerator ();
        while(msg.MoveNext ())
        {
         System.Messaging .Message oc=msg.Current ;
         Od od=oc.Body  as Od ;
         this.richTextBox1.AppendText(od.Name +":"+od.City +":"+od.Time +";\r\n");
        
        }

       }
      }
      private void button4_Click(object sender, System.EventArgs e)
      {
       if(MessageQueue.Exists(@".\private$\dhzTrans"))
       {
        this.msq =new MessageQueue(@".\private$\dhzTrans");
       }
       else
       {
        this.msq=MessageQueue.Create(@".\private$\dhzTrans",true);
       }
       this.richTextBox1.AppendText("==================\r\n");
       this.richTextBox1.AppendText(msq.QueueName +":创建成功!\r\n");
      
      }
      private void button5_Click(object sender, System.EventArgs e)
      {
       
       this.msq=new MessageQueue(@".\private$\dhzTrans");
       if(this.msq.Transactional)
       {
        Od od=new Od("万卿","景德镇",DateTime.Now.ToString("u"));
        MessageQueueTransaction myTransaction = new
                    MessageQueueTransaction();
              myTransaction.Begin();
           msq.Send(od,myTransaction);
                    myTransaction.Commit();
        this.richTextBox1.AppendText("OK!发送成功:"+od.Time+"\r\n" );
       }

      }
      private void button6_Click(object sender, System.EventArgs e)
      {
       this.msq=new MessageQueue(@".\private$\dhzTrans");
       if(this.msq .Transactional )
       {
        MessageQueueTransaction myTransaction = new MessageQueueTransaction();
        this.msq.Formatter=new System.Messaging.XMLMessageFormatter (new Type[]{Type.GetType("WinMsmq.Od" )});
        myTransaction.Begin();
        System.Messaging.Message ms=msq.Receive(myTransaction);
        Od od=ms.Body as Od ;
        this.richTextBox1.AppendText(od.Name +":"+od.City +":"+od.Time +";\r\n");
        myTransaction.Commit();
        this.richTextBox1.AppendText("OK!发送成功\r\n");
       }
      }
      private void Read(object sender, System.EventArgs e)
      {
       this.msq=new MessageQueue(@".\private$\dhzTrans");
       if(this.msq.Transactional)
       {
        MessageQueueTransaction myTransaction = new MessageQueueTransaction();
        msq.ReceiveCompleted += new ReceiveCompletedEventHandler(MyReceiveCompleted);
        this.msq.Formatter=new System.Messaging.XmlMessageFormatter (new Type[]{Type.GetType("WinMsmq.Od" )});
        myTransaction.Begin();
                    msq.BeginReceive();
        Form1.signal.WaitOne ();
        myTransaction.Commit ();
       }
      }
      private  void MyReceiveCompleted(Object source,ReceiveCompletedEventArgs asyncResult)
      {
       try
       {
        MessageQueue mq = (MessageQueue)source;
        System.Messaging .Message m = mq.EndReceive(asyncResult.AsyncResult);
        Form1.signal.Set ();
                    Od od=m.Body as Od ;
         this.richTextBox1.AppendText ("Read:"+od.Name +":"+od.City +":"+od.Time +"\r\n"+"插入数据库完成\r\n");
        mq.BeginReceive();
       }
       catch(MessageQueueException c)
       {
             this.richTextBox1.AppendText("Error:"+c.Message +"\r\n");
        this.button5.Enabled=false;
       }
                // Handle other exceptions.
               
       
      }
      private void button7_Click(object sender, System.EventArgs e)
      {
       this.richTextBox1.Clear ();
      }
      private void delPubmsg_Click(object sender, System.EventArgs e)
      {
       //删除创建的公共队列
       System.Messaging.MessageQueue.Delete (qryname);
      }
      private void srPub_Click(object sender, System.EventArgs e)
      {
          MessageQueue[]  mq=System.Messaging.MessageQueue.GetPublicQueuesByMachine ("dhz");
       for(int i=0;i<mq.Length ;i++)
       {
        this.richTextBox1.AppendText(mq[i].QueueName +":\r\n");
       }

      }
      private void sendToPub_Click(object sender, System.EventArgs e)
      {
          if(this.pubMsq==null)
          this.pubMsq=new MessageQueue(this.qryname );
       if(this.pubMsq.Transactional  )
       {
        Od od=new Od("万卿","景德镇",DateTime.Now.ToString("u"));
        MessageQueueTransaction myTransaction = new
         MessageQueueTransaction();
        myTransaction.Begin();
        pubMsq.Send(od,myTransaction);
        myTransaction.Commit();
       }
      }
      private void readFromPub_Click(object sender, System.EventArgs e)
      {
       this.pubMsq=new MessageQueue(this.qryname );
       if(this.pubMsq.Transactional)
       {
        MessageQueueTransaction myTransaction = new MessageQueueTransaction();
        pubMsq.ReceiveCompleted += new ReceiveCompletedEventHandler(MyReceiveCompleted);
        this.pubMsq.Formatter=new System.Messaging.XmlMessageFormatter (new Type[]{Type.GetType("WinMsmq.Od" )});
        myTransaction.Begin();
        pubMsq.BeginReceive();
        Form1.signal.WaitOne ();
        myTransaction.Commit ();
       }
      
      }

      

     }
    }
    /////////////////////////================
    public class Od
     {
      public Od()
      {
       //
       // TODO: 在此处添加构造函数逻辑
       //
      }
      public Od(string  na,string cty,string timestr)
      {
       this.name=na;
       this.city=cty;
       this.time=timestr;

      }
      private string  time="";
      private string name;
      private string city;
      public string Name
      {
       get{return this.name ;}
       set{this.name=value;}
      }
      public string City
      {
       get{return this.city ;}
       set{this.city=value;}
      }
      public string Time
      {
       get{return this.time ;}
       set{this.time=value;}
      }
     }
    =======================App.config
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <appSettings>
      <!--ComputerName-->
      <!--dhz:是域控制器所在的计算机名:-->
         <add key="QcName" value="dhz\FormatName:Public=620B1BFB-18E9-4d80-B869-FF6FB2DFDD08"></add>
      </appSettings>
    </configuration>


  • 相关阅读:
    Vijos 1083 小白逛公园(线段树)
    [NOIP2012提高组] CODEVS 1200 同余方程(扩展欧几里德算法)
    sshpass安装以及使用
    python 判断操作系统以及操作系统版本号
    subprocess.run()用法python3.7
    SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xd0 in position 2: invalid continuation byte
    linux动态监控dstat&&glances&&psutil&&bottle
    subprocess.Popen()
    centos解决bash: telnet: command not found...&& telnet: connect to address 127.0.0.1: Connection refused拒绝连接
    pexpect &&pxssh
  • 原文地址:https://www.cnblogs.com/zengwei/p/730695.html
Copyright © 2020-2023  润新知