Threads in a multi-threaded application may or may not be associated with each other. For example, each program has a main thread used to generate other sub-threads, so the main thread becomes the controller of all other threads. There are three common methods to define the relationship between threads in A multithreaded application:
1. Main thread and working thread model
2. Peer-to-Peer thread model
3. MPS queue thread model
We will discuss each model in detail and use some code to let you know how to implement them in your own program.
Main thread and working thread model
This is the most common thread model and the model that has been used since now. 3 indicates:
Figure 3
In the main thread and working thread model, the main thread receives all the input and passes the input parameters to other threads for specific tasks. The main thread can wait/not wait for the worker thread to finish. In this model, the worker thread does not directly deal with the input resources, but uses the main thread as a transit. For example, we have a Windows form program with three buttons on it to trigger three different events:
1. Get data from a web service
2. Get data from a database
3. Do some tasks such as intercepting XML files
This is the simplest thread model. The Main thread is included in the Main () method. This model is very common in client interface programs.
Let's look at some code to better describe this problem. Now let's take a look at the next form program:
When you click a button, it will trigger a worker thread that executes some operations and display the returned results in a blank space under the button. We do not discuss the interface in detail; here only part of the code is given, all the code please download the http://www.bkjia.com/uploadfile/2012/0306/20120306090032831.zip from here
/*************************************
/* Copyright (c) 2012 Daniel Dong
*
* Author: oDaniel Dong
* Blog: o www.cnblogs.com/danielWise
* Email: o guofoo@163.com
*
*/
Using System;
Using System. Collections. Generic;
Using System. Linq;
Using System. Text;
Using System. Collections;
Namespace MainWorker
{
Public class MainWorker
{
Public ArrayList CalculatorFactors (double number)
{
If (number <3)
{
Return null;
}
Else
{
ArrayList factors = new ArrayList ();
Factors. Add ("1 ");
For (double current = 2; current <= number-1; current ++)
{
If (double) (Math. Floor (number/current) * current) = number)
{
Factors. Add (current. ToString ());
}
}
Factors. Add (number. ToString ());
Return factors;
}
}
Public long CalculatorFactorial (int number)
{
If (number <0)
{
Return-1;
}
If (number = 0)
{
Return 1;
}
Else
{
Long returnValue = 1;
For (int current = 1; current <= number; current ++)
{
ReturnValue * = current;
}
Return returnValue;
}
}
}
}
The above code is very easy to understand and encapsulated into a class for modularity reasons. The first method returns an ArrayList containing all the factorial values passed to it, while the second method simply returns a long integer number. Remember that factorial changes are very fast. The factorial of 13 is 6,227,020,800. The calculation method does not take a long time for the processor, but it can be used to describe this model.
Public partial class frmCalculator: Form
{
MainWorker threadMthods;
Delegate void UpdateValue (string text );
Public frmCalculator ()
{
InitializeComponent ();
ThreadMthods = new MainWorker ();
}
The constructor instantiates a MainWorker object. The code for handling button events is as follows:
Private void upload factors_click (object sender, EventArgs e)
{
Thread calculatorFactors = new Thread (new ThreadStart (FactorsThread ));
CalculatorFactors. Start ();
}
Void FactorsThread ()
{
ArrayList val = threadMthods. CalculatorFactors (200 );
StringBuilder sb = new StringBuilder ();
For (int count = 0; count <= val. Count-1; count ++)
{
Sb. Append (string) val [count]);
If (count <val. Count-1)
{
Sb. Append (",");
}
}
// Create and invoke the delegate with the new value
UpdateValue updVal = new UpdateValue (DisplayValue );
String [] args = {sb. ToString ()};
This. Invoke (updVal, args );
}
The worker factors_click () method uses the FactorsThread () method to instantiate a new thread. This thread will format the return value of the MainWorker. CalculatorFactors () method.
This method needs to be packaged because the thread method cannot return values.
Private void upload factorials_click (object sender, EventArgs e)
{
Thread calculatorFactorial = new Thread (new ThreadStart (FactorialThread ));
CalculatorFactorial. Start ();
}
Void FactorialThread ()
{
Long val = threadMthods. CalculatorFactorial (20 );
// Create and invoke the delegate with the new value
UpdateValue updVal = new UpdateValue (DisplayValue );
String [] args = {val. ToString ()};
This. Invoke (updVal, args );
}
The FactorialThread () method is simpler. Whenever the restore factorial button is clicked, the main thread will trigger a new thread and wait until the result is ready to update the lblResult text box.
This is a very simple example of the main thread and working thread. Obviously, this example can easily be changed to the method for processing database connections or other time-consuming activities.
However, when using this model, you should be careful with several thread-related issues. You may use a thread to generate a thread and allow the thread to access the same resource, resulting in an infinite loop of threads.
This is the simplest model, but it is also the model that requires programmers to do the most work.
Also, in this model, each thread is independent of each other, and each thread is controlled by its parent thread-in this example, it is the main thread.
The next article will introduce the peer-to-peer thread model...
From DanielWise