C # Message Queuing application-2

Source: Internet
Author: User
Tags export class loop case message queue terminates
Inside this array, the CWorker class creates an implementation version of the CWorkerThread class
This. The CWorkerThread class (to be discussed below) is an abstract class that must be inherited. Export
class defines how messages are handled:
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;
Define a secondary type and insert it into the worker thread structure
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");
}
Add a call to an array
Athreads.insert (idx, wtbase);
}

Once all the objects have been created, you can call the start side of each thread object by invoking the
method to start them:
foreach (CWorkerThread cthread in Athreads)
Cthread.start ();

The Stop, Pause, and Continue methods perform similar actions in the Foreach loop.
The Stop method has the following garbage collection operations:
Gc. SuppressFinalize (this);

The Stop method is called in the class destructor, so that the Stop party is not explicitly called
The object can also be terminated correctly in the case of the method. If you call the Stop method, you do not need to analyze the
constructor. The SuppressFinalize method prevents the call to the object's Finalize method (analysis

The actual implementation of the constructor).

CWorkerThread Abstract class

CWorkerThread is a cworkerthreadappspecifc, CWorkerThread
Abstract classes inherited by Roundrobin and cworkerthreadassembly. Regardless of the processing
Most processing of the queue is the same, so the CWorkerThread class provides this functionality.
This class provides an abstract method (which must be overridden by the actual method) to manage resources and process messages.

Class is once again implemented by the Start, Stop, Pause, and Continue methods.
The input and error queues are referenced in the Start method. In the. NET framework, messages are made by System.
Messaging namespace Processing:
Try to open the queue and set the default read and write properties
MessageQueue mqInput = new MessageQueue (sinputqueue);
MqInput.MessageReadPropertyFilter.Body = true;
MqInput.MessageReadPropertyFilter.AppSpecific = true;
MessageQueue mqerror = new MessageQueue (serrorqueue);
If you are using MSMQ COM, set the formatter to ActiveX
Mqinput.formatter = new ActiveXMessageFormatter ();
Mqerror.formatter = new ActiveXMessageFormatter ();

Once a message queue reference is defined, a thread is created for the actual handler function
(called processmessages). In the. NET framework, use the System.Threading
Namespaces are easy to implement threading:
Procmessage = new Thread (new ThreadStart (processmessages));
Procmessage.start ();

The ProcessMessages function is a boolean-based processing loop. When the value is set to
False, the processing loop terminates. Therefore, the Stop method of the thread object only sets this Boolean
Value, and then closes the open message queue and joins the thread with the main threads:
Joining service threads and processing threads
BRun = false;
Procmessage.join ();
To close an open message queue
Mqinput.close ();
Mqerror.close ();

The Pause method only sets a Boolean value that causes the processing thread to hibernate for half a second:

if (bpause)
Thread.Sleep (500);

Finally, each Start, Stop, Pause, and Continue method invokes the abstract
OnStart, OnStop, OnPause, and OnContinue methods. These abstract methods are used to implement
class provides hooks to capture and release the required resources.

The ProcessMessages Loop has the following basic structure:
Receives a message.
If the message has a successful receive, the abstract ProcessMessage method is called.
If receive or ProcessMessage fails, the message is sent to the error queue.

Message Minput;
Try
{
Read from the queue and wait 1 seconds
Minput = mqinput.receive (new TimeSpan (0,0,0,1));
}
catch (Messagequeueexception mqe)
{
Set the message to NULL
Minput = null;
Review the error code to see if it timed out
if (MQE. ErrorCode! = ( -1072824293))//0xc00e001b
{
If not timed out, issue an error and log the error number
LogError ("Error:" + mqe. Message);
Throw mqe;
}
}
if (minput! = null)
{
Get a message to process, call the process message abstract method
Try
{
ProcessMessage (Minput);
}
Error capturing a known exception state
catch (Cworkerthreadexception ex)
{
Processerror (Minput, ex. Terminate);
}
Catch unknown exception and call Terminate
Catch
{
Processerror (Minput, true);
}
}

The Processerror method sends the wrong message to the error queue. In addition, it may also lead to
To terminate the thread by sending an exception. If the ProcessMessage method throws a terminating error or CWorker
The threadexception type, which will perform this operation.

CWorkerThread Export Class

Any class inheriting from CWorkerThread must provide OnStart, OnStop, on
Pause, OnContinue, and ProcessMessage methods. OnStart and OnStop methods obtained
Take and release processing resources. The OnPause and OnContinue methods allow temporary release and re-
Access to these resources. The ProcessMessage method should process the message and, when a failure event occurs,
Cworkerthreadexception abnormal hair.

Because the CWorkerThread constructor defines run-time parameters, the export class must call the base class
constructor function:
Public cworkerthreadderived (CWorker v_cparent, Workerthread
Formatter v_wfthread)
: Base (V_cparent, V_wfthread) {}

The export class provides two types of processing: sending a message to another queue, or calling a group
Method. Two implementations of receiving and sending messages use loop technology or application offsets (guaranteed
Remain in the message appspecific attribute) as a determinant of which queue to use. This scenario
The configuration file in should include a list of queue paths. OnStart and OnStop methods of implementation
References to these queues should be turned on and off:
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 ();
}

In these scenarios, the processing of the message is simple: Send the message to the necessary output queue. In
In the loop case, this process is:
Try
{
Mqoutput[inextqueue]. Send (V_minput);
}
catch (Exception ex)
{
If an error forces a terminating exception
throw new Cworkerthreadexception (ex. Message, True);
}
Calculate the next queue number
inextqueue++;
Inextqueue%= iqueues;

The latter method of invoking a component with a message parameter is more interesting to implement. ProcessMessage
Method uses the IWebMessage interface to dial in a. NET component. OnStart and OnStop Fang
method to obtain and release a reference to this component.

The configuration file in this scenario should contain two items: the full class name and the file containing the class
Position. Call the Process method on the component, as defined in the IWebMessage interface.

To get an object reference, you need to use the Activator.CreateInstance method. This letter
The number requires an assembly type. Here, it is exported from the assembly file path and the class name.
Once the object reference is obtained, it is put into the appropriate interface:
Private IWebMessage iwmsample;
private string Sfilepath, Stypename;
Save assembly path and type name
Sfilepath = wfthread.outputname[0];
Stypename = wfthread.outputname[1];
Get a reference to the necessary object
Assembly asmsample = Assembly.LoadFrom (Sfilepath);
Type typsample = Asmsample.gettype (stypename);
Object objsample = Activator.CreateInstance (typsample);
The necessary interfaces defined to the object
Iwmsample = (iwebmessage) objsample;

Once the object reference is obtained, the ProcessMessage method will call on the IWebMessage interface.
Process method:
Webmessagereturn wbrsample;
Try
{
Defining parameters for method calls
string Slabel = V_minput.label;
String sbody = (string) v_minput.body;
int iappspecific = v_minput.appspecific;
Calling the method and catching the return code
Wbrsample = Iwmsample.process (Slabel, Sbody, iappspecific);
}
catch (InvalidCastException ex)
{
Force a non-terminating exception if an error occurs in the message content
throw new Cworkerthreadexception (ex. Message, false);
}
catch (Exception ex)
{
Force a terminating exception if an assembly is called incorrectly
throw new Cworkerthreadexception (ex. Message, True);
}
If there is no error, check the return status of the object call
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
}

Provides a sample component that writes the message body to a database table. If a critical database error is captured
Error, you may want to terminate the process, but here, just mark the message as
Interest.

Because the class instance created in this example may acquire and retain expensive database resources, the
To release and re-obtain the object reference using the OnPause and OnContinue methods.

Testing equipment

As in all good applications, the detection device is used to monitor the application's
State.. NET Framework greatly simplifies the use of event logs, performance counters, and Windows Management Instrumentation
Device (WMI) into the application process. Messaging applications use time logs and performance meters
Both are from the System.Diagnostics assembly.

In the ServiceBase class, you can automatically enable the event log. In addition, ServiceBase
The EventLog member supports writing to the application event log:
EventLog.WriteEntry (Smymessage, eventlogentrytype.information);

For applications that write to the event log instead of the application log, it is easy to
Create and get a reference to the EVENTLOG resource (as you did in the CWorker class),
And be able to log entries using the WriteEntry method:
Private EventLog CLog;
string ssource = Servicecontrol.servicecontrolname;
String sLog = "Application";
See if the source exists and if it does not, create the source
if (! EventLog.SourceExists (ssource))
EventLog.CreateEventSource (ssource, SLog);
Create a Log object and reference the source that is now defined
CLog = new EventLog ();
Clog.source = ssource;
Write entries in the log to indicate that the creation was successful
Clog.writeentry ("created successfully", eventlogentrytype.information);

The. NET framework greatly simplifies performance counters. For each processing thread, thread export
Users and the entire application, this messaging application can provide counters for tracking
And the number of messages processed per second. To provide this functionality, you need to define performance counters
, and then add the corresponding counter instance.

The categories of performance counters are defined in the service OnStart method. These categories represent a total of two
Count-The total number of messages and the number of messages processed per second:
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);

Once a performance counter category is defined, the PerformanceCounter object is created to
Ask the counter instance function. The PerformanceCounter object requires a category, a counter name, and a
An optional instance name. For worker processes, the process name from the XML file will be used, substituting
Code is as follows:
Pcmsgtotworker = new PerformanceCounter ("MSDN Message Service",
"Messages/total", sprocessname);
Pcmsgsecworker = new PerformanceCounter ("MSDN Message Service",
"Messages/second", sprocessname);
Pcmsgtotworker.rawvalue = 0;
Pcmsgsecworker.rawvalue = 0;

To increase the value of a counter, you simply need to invoke the appropriate method:

Pcmsgtotworker.incrementby (1);
Pcmsgsecworker.incrementby (1);

Finally, when the service terminates, the installed performance counter category should be removed from the system:

Performancecountercategory.delete ("MSDN Message Service");

Because performance counters work in the. NET framework, you need to run a special service.
This service (Perfcounterservice) provides shared memory. Counter information is written to the shared
Memory and is read by the performance counter system.

Installation

Before we finish, let's briefly introduce the installation and the Installutil.exe
Installation tools. Because this application is a Windows service, it must use the Installutil.exe
To install. Therefore, you need to use one from the System.Configuration.Install assembly
The installer class that inherits from:
public class Serviceregister:installer
{
Private ServiceInstaller ServiceInstaller;
Private ServiceProcessInstaller Processinstaller;
Public Serviceregister ()
{
Create a Service Setup program
ServiceInstaller = new ServiceInstaller ();
Serviceinstaller.starttype = servicestart.manual;
Serviceinstaller.servicename = Servicecontrol.servicecontrol
Name;
Serviceinstaller.displayname = Servicecontrol.servicecontrol
Desc;
Installers.add (ServiceInstaller);
Create a Process Setup program
Processinstaller = new ServiceProcessInstaller ();
Processinstaller.runundersystemaccount = true;
Installers.add (Processinstaller);
}
}

As shown in this example class, for a Windows service, the service and service processes require a
Setup program to define the account that runs the service. Other installers allow registering the event log and
Resources such as performance counters.

Summarize

As you can see from this. NET Framework application example, previously only Visual C + +
Applications that programmers can write are now implemented using simple object-oriented programs. Do
Our focus is C #, but this article also applies to Visual Basic and
Managed C + +. The new. NET Framework enables developers to use any programming language to create
Powerful, scalable Windows applications and services.

The new. NET framework not only simplifies and expands the possibilities of programming, it also makes it easy to
Application detection devices that people often forget (such as performance monitoring counters and event log notifications)
Merge into the application. Although the application here does not use the Windows Management Instrumentation device
(WMI), but the. NET framework can also apply it.

The above is the C # Message Queuing application-2 of the content, more related articles please pay attention to topic.alibabacloud.com (www.php.cn)!

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.