Use thread

xiaoxiao2021-03-06  83

Use thread

Greg EwingClarity Consulting Inc. 2002 Abstract: This article discusses the threads of various modes (single thread, unit thread, and free thread) and how the usage is used. At the same time, a C # language code example using threads is also provided to help you write applications that use threads. This article also discusses some important issues in multi-thread code. Download (English) sample file. (Note that in the sample file, the programmer's annotation is used in English. This article is translated into Chinese to make it easy for the reader.) Directory Introduction Thread Background Sample Application Multithreaded Code Question Summary Introduction Multithreaded Microsoft ® Message Queue (MSMQ) trigger application is always a fearful thing. However, the emergence of .NET framework threads and messages make this work easier than before. These classes allow you to use any language for the .NET framework to write multi-threaded applications. Previously, tools such as Microsoft Visual Basic® were very limited. Therefore, C has to be used to write multi-threaded code, construct a solution consisting of multiple processes or ActiveX DLL through Visual Basic (this solution is not ideal), or simply gives up multithreading. Use the .NET framework, you can build a variety of multi-threaded applications without considering which language is selected. This article will gradually introduce the process of building a multi-threaded application from the Microsoft message queue. This article will focus on two namespace system.threading and system.Messaging. Sample code is written in C # language, but you can easily convert it to the language you are using. Thread background In the Win32 environment, thread has three basic modes: single thread, unit thread, and free thread. Some applications you originally written in a single thread are probably a single-threaded application, including only threads corresponding to the application process. The process can be defined as an application's instance, with the memory space of the application. Most Windows applications are single-threaded, that is, all work is done with a thread. The unit thread unit thread is a slightly complex thread mode. The code for marking the unit thread can be performed in its own thread and is limited to its own unit. Threads can be defined as entities owned by the process. This process will be scheduled. In unit thread mode, all threads run within the respective subsection ranges in the main application memory. This mode allows multiple code instances to run independently. For example, before .NET, Visual Basic is limited to creating unit thread components and applications. Free thread free thread is the most complex thread mode. In the free thread mode, multiple threads can simultaneously call the same methods and components. Unlike unit threads, the free thread will not be limited to stand-alone memory space. You may need to use free threads when your application must make a large similar and independent mathematical calculation. In this case, you need to generate multiple threads to use the same code example to perform calculations. It may be C developers only write application developers who write free thread applications because languages ​​like Visual Basic 6.0 are almost impossible to write free thread applications. Using Thread Mode In order for you have a certain concept of thread mode, we can imagine it to move from a house to another. If you use a single-threaded method, you will need to complete all your work from the package to the bag to the package. If you use the unit thread mode, you invite a good friend to help. Every friend works in a separate room and can't help people working in other rooms. They are responsible for their own space and the items in space. If you use a free thread method, you still invite the same friends to help, but all friends can work in any room and package items.

Similar to this, your house is a process running all threads. Each friend is a code instance, handling items for the resources and variables of the application. This example explains the advantages and disadvantages of different thread modes. The unit thread is faster than a single thread because there are multiple component instances at work. In some cases, the free thread is more efficient than the unit thread, because everything happens, and you can share all resources. However, this may have problems when multi-thread changes shared resources. Suppose one starts to use the box to pack kitchen utensils, at this time, another friend came in, to use the same box to package the bathroom. The first friend sticked to "kitchen utensils" on the box, and another friend covers the original label with a "toiletries" tag. As a result, when you are unpacking, the kitchen supplies will be moved to the bathroom. The first step in the sample application is to check the design of the sample application. The application will generate multiple threads, and each thread listens for messages from the MSMQ queue. This example uses two classes, main FORM classes, and custom MQListen classes. The FORM class will process the user interface and create, manage, and destroy the auxiliary thread. The MQListen class contains all code, including the message queue factors required for the auxiliary thread run. Preparing an application To launch an application, open Visual Studio .NET and create a new C # Windows application called MultithreadedMqlistener. Open the properties of the form, name it queuelistenerform. After drawing the initial form, drag and drop two labels, two buttons, one status bar, and two text boxes to the form. Name the first text box Server, and the second text box named queue. Name the first button StartListening, the second button is named stoplistence. You can keep the default name STATUSBAR1 in the status bar. Next, click the Project menu and click Add Reference to add a reference to System.Messaging Namespace. Find and select System.Messaging.dll in the .NET component list. Namespace contains classes used with MSMQ queue communication. Next, click the File menu, and then click Add New Item to add a new class in the project. Select the Class template and name it Mqlisten. Add the following USING statement at the top of the class: // C #

Using system.threading;

Using system.Messaging; System.Threading Name Space Allows you to access all necessary thread features, in this case, you can access the Thread class and the ThreadInterruPtexception constructor. This namespace also includes many other advanced features, which are not discussed in detail. System.Messaging Namespace Allows you to access the MSMQ function, including send messages to the queue and receive queue messages. In this case, you will use the MessageQueue class to receive messages. You must also add USING SYSTEM.THREADING in the main form code. After all reference is in place, you can start writing code. The auxiliary thread first needs to build a MQListen class that encapsulates all threads. Insert the following code into mqlisten. // c #

Public Class Mqlisten

{

PRIVATE STRING M_MACHINENAME;

PRIVATE STRING M_QUEUENAME;

// Construct the function to receive the necessary queue information.

Public mqlisten (String Machinename) {String Queuename

m_machinename = machinename;

m_queueename = queuename;

}

// Each thread is used to listen to the only method of MQ messages

Public void listen ()

{

// Create a MessageQueue object.

System.Messaging.MessageQueue MQ = New

System.Messaging.MessageQueue ();

/ / Set the path properties of the MessageQueue object.

Mq.path = m_machinename "// private $ //" m_queueename;

// Create a Message object.

System.Messaging.Message Message = New

System.Messaging.Message ();

// Repeat the above step until the interrupt is received.

While (True)

{

Try

{

// Sleep to capture the interrupt when the interrupt is issued.

System.Threading.Thread.sleep (100);

// Set the Message object to be equal to the results of the reception function.

// Duration (days, hours, minutes, seconds).

Message = mq.receive (New TimeSpan (0, 0, 0, 1));

/ / Display the label of the received message

System.Windows.Forms.MessageBox.show ("label:" message.label);

}

Catch (ThreadInterruptedException E)

{

// capture ThreadInterrupt from the main thread and exit.

Console.writeline ("EXITING THREAD");

Message.dispose ();

Mq.dispose ();

Break;

}

Catch (Exception genericexception)

{

// Capture all exceptions thrown during the receiving process.

Console.writeline (genericexception.message);

}

}

}

} The code discussion The MQListen class contains a function different from the constructor. This function encapsulates all the work to be performed. In the main thread, you pass a reference to the thread constructor to execute the function when starting the thread. The first thing for Listen is to set a message queue object. The MessageQueue constructor is overloaded through three implementations. The first implementation uses two parameters: a string parameter, specifies the location of the listening queue; a Boolean value parameter indicates whether the first application for the access queue gives exclusive read queue permissions. The second implementation only uses the queue path parameters, and the third implementation does not use parameters. For the sake of simplicity, you can use the third implementation to allocate the path in the next row. If you reference the queue, you must create a message object. There are three messaging functions. If you want to write a message to the queue, you can use the first two implementations. Both implementations use two objects: one is an object in the message body; one is the IMESSAGEFORMATTER object that defines how objects are serially serialized to the message body. In this example, you will read data from the queue to initialize the empty message object. After initializing the object, you need to enter the main loop of all work. Then, when the main thread calls Interrupt to terminate these threads, only the thread is interrupted in a wait, sleep or connection state. If it is not in the above three states, it will be interrupted until a next time you enter the three states. To ensure that the auxiliary thread goes into wait, sleep or connection, call the Sleep method located in the System.Threading namespace. For C and Visual Basic developers who have used the Windows API sleep function, the SLEEP method is not unfamiliar. It only uses a parameter: threads at the number of sleep states. If you never call the SLEEP, the secondary thread will never enter the status of the interrupt request, and will continue without restriction unless you manually turn off the process. There are two implementations in the MQ Receive method. The first implementation does not use parameters, will wait for the reception message. Second implementation (this example uses this implementation) Use the TimeSpan object to specify a timeout value. The Timespan constructor contains four parameters: days, hours, minutes, and seconds. In this case, the Receive method will wait a second before the timeout and returns. The received message will be assigned to the previously created message object, and then it can be processed. This example opens a message box with a label and deletes this message. If you want to use this code in actual use, you can place any message processing code here. When the auxiliary thread receives the Interrupt request, a ThreadInterruptedException is issued. To capture this exception, include the Sleep and Receive functions in the Try-Catch block. You should specify two capture: the first one for capturing an abnormality, the second error exception for processing captured. When you capture an interrupt exception, first write it to the debug window that is exiting. Next, call the DISPOSE method for the queue object and message object to ensure that all memory is empty and sent to the memory recovery. Finally, interrupt the While loop. After the function exits the While cycle, the associated thread will end immediately, the code is 0. In the debug window, you will see a message, such as "THREAD '' (0x660) HAS EXITED with CODE 0 (0x0)" (thread '' (0x660) has exited, code is 0 ( 0x0))).

Now, the thread has exited the environment and has been automatically destroyed. The main thread and auxiliary thread do not need to perform a special clear operation. The main point of the main form is to add code to the form to generate a secondary thread and launch the MQListen class for each auxiliary thread. First, add the following function to the form: // C # private void startthreads ()

{

INT loopCounter; // thread count

StoplisteningFlag = false; // tracking the auxiliary thread

// terminate the flag.

// Declare a array containing 5 threads as a secondary thread.

Thread [] threadArray = new thread [5];

// The statement contains all the codes of all the code of the auxiliary thread.

MQListen Objmqlisten = New

Mqlisten (this.servername.text, this.queuname.text);

For (loopcounter = 0; loopCounter

{

// Create a THREAD object.

ThreadArray [loopcounter] = new thread (New

ThreadStart (objmqlisten.listen));

// Start the thread will call ThreadStart commission.

ThreadArray [loopcounter] .Start ();

}

Statusbar1.text = loopCounter.toString () "listener threads started";

While (! stoplisteningflag)

{

// Wait for the user to press the stop button.

// During the waiting process, let the system handle other events.

System.windows.Forms.Application.doevents ();

}

STATUSBAR1.TEXT = "stop request received, stopping threads";

// Send an interrupt request to each thread.

For (loopcounter = 0; loopCounter

{

ThreadArray [loopcounter] .interrupt ();

}

Statusbar1.text = "all threads have been stopped";

} Code Discussion To start this function, create a thread array containing 5 items. This array will keep the reference to all threads for future use. The constructor of the MQListen class uses two parameters: contains the computer name of the message queue and the name of the queue to be listened. The constructor uses the value in the text box to assign these two parameters. To create a thread, you need to enter the loop to initialize each thread object. The Thread constructor requires you to deliver a delegate that points to the function you want to call when calling the START method of the thread. You want the thread to start using the MQListenTen.listen function, but the thread is not a delegate. In order to meet the requirements of the thread constructor, you must pass a ThreadStart object that will create a delegation of a given function name. At this point, pass a reference to the ThreadStart object to the MQListenTen.listen function. Since the array element has been initialized, please call Start to start the thread. After all threads start, use the appropriate messages to update the status bar in the form. With the running and listening queue of the thread, the main thread will wait for the user to request the application to stop listening. To do this, the main thread will enter a while loop until you click the Stoplistening button to change the value of the stoplisteningflag. In this waiting cycle, the application will allow the application to use the Forms.Application.doEvents method to handle other jobs that need to be processed. This is the same as the old doevents method for readers who are familiar with Visual Basic. For readers who are familiar with C , this is equal to writing a MSG pump. When the user clicks on the stoplistening button, the loop will exit and enter the thread shutdown code. To turn off all threads, the code must check the thread array and send an interrupt signal to each thread. Inside this loop, please call the Interrupt method to each thread in the array. The code in the MQListen class will continue to be performed normally before calling this method. Therefore, you can call each auxiliary thread for Interrupt without having to consider whether the thread is processing other events. After completing, the thread class will process all threads. Finally, update the status bar in the main form before exiting. Now you need to add code after the button. Add the following code to the Click event of the StartListening button: // c # statusbar1.text = "starting threads";

StartThreads (); this will update the status bar and call the StartThreads method. For the stoplistening button, you only need to use the following code to set the stoplisteningflag to true: // c #

StoplisteningFlag = true; the last step is to add a window size variable for StoplisteningFlag. Add it to the top of the form code: // C #

转载请注明原文地址:https://www.9cbs.com/read-94478.html

New Post(0)