Multithreading Pass Parameters

Source: Internet
Author: User
The article will be on Microsoft. Net

Development of multithreaded programming a simple summary, I believe that will be helpful to everyone. Here is a concrete look:

There is no need to pass parameters or return parameters

We know that the most intuitive way to start a thread is to use the thread class, as follows:

The following is a reference fragment:

ThreadStart threadstart=new ThreadStart (Calculate);

Thread thread=new thread (ThreadStart);

Thread. Start ();

public void Calculate () {

Double diameter=0.5;

Console.Write ("The area of Circle with a diameter of" diameter,diameter*math.pi);

}

Above we have defined a ThreadStart type of delegate, this delegate provides a way for a thread to execute: Calculate, in this method, calculates the area of a circle with a diameter of 0.5 and outputs it. This constitutes the simplest example of multithreading, which in many cases is sufficient, Then threadstart this delegate is defined as void ThreadStart (), which means that the method being executed cannot have parameters, which is obviously a big shortcoming, and in order to make up for this flaw, smart programmers come up with many good methods that we'll introduce in the section on needing to pass multiple parameters. , here we introduce first. NET to solve this problem and set another delegate: Is Parameterizedthreadstart, I will be in detail below.

Need to pass a single parameter

The following is a reference fragment:

Parameterthreadstart is defined as void Parameterizedthreadstart (object state)?? The start function of the thread defined by this delegate can accept an input parameter, as follows

Parameterizedthreadstart threadstart=new Parameterizedthreadstart (Calculate)

Thread Thread=new thread ()

Thread. Start (0.9);

public void Calculate (object arg) {

Double diameter=double (ARG);

Console.Write ("The area of Circle with a diameter of" diameter,diameter*math.pi);

}

Example 2

The Calculate method has a parameter of type object, and although there is only one argument, and it is of type object, a type conversion is still required, but it is good to have parameters, and by combining multiple parameters into a class and then passing an instance of the class as a parameter, You can implement multiple parameter passes

Need to pass multiple parameters

Although by wrapping the required parameters into a class, the delegate Parameterizedthreadstart can pass multiple parameters, but because the incoming parameter of the delegate is object, it is inevitable that parameter conversions are necessary, and there are several commonly used parameter passing methods below. Let's see one by one.

Using a specialized thread class

This is a classic model that many programmers love to use, and in simple terms, is to put the method that needs to be executed by another thread, and the parameters he needs to be placed in a class, the parameter as a property of the class, the instance of the class is declared when invoked, and then the property is initialized, and the method executes directly using the initialized property in the class. So that the method itself does not require arguments, and the effect of multiple-parameter transmission, so the use of the first mentioned in this article without parameters of the ThreadStart delegate can be, and because the need to implement methods and parameters are placed in a class, fully embodies the characteristics of the object-oriented. The specific methods are as follows

Or as an example of the method of calculating the area, we wrap this method in a class, and the input parameter diameter (diameter) is a field of this class.

The following is a reference fragment:

public class Mythread

{

public double diameter=10;

public double result=0;

public mythread (int diameter)

{

This. diameter = diameter;

}

public void Calculate ()

{

Console.WriteLine ("Calculate Start");

Thread.Sleep (2000);

result = Diameter*math.pi;;

Console.WriteLine ("Calculate end, diameter are, result are", this. diameter, result);

}

}

Mythread t=new Mythread (5.0);

ThreadStart threadstart=new ThreadStart (t.calculate)

Thread thread=new thread (ThreadStart);

Thread. Start ();

Example 3

This method passes the parameter to the property share, how many variables to pass, from the encapsulation, the logic and logic involved in packaging the data is also very good, this method also has a smart variant, using the anonymous method, this variant is not even the independent classes are omitted, I now give this method

The following is a reference fragment:

Double diameter = 6;

Double result=0;

Thread ta = new Thread (new ThreadStart (delegate)

{

Thread.Sleep (2000);

Result=diameter * MATH.PI;

Console.WriteLine ("Anonymous Calculate end, diameter are, result are", diameter, result);

}));

Ta. Start ();

This method is the same as the previous example, which is to pass the parameter to the variable invocation, thus canceling the parameter pass, but, the latter makes full use of the anonymous method of a property, that is, can directly use the current context of local variables, such as the diameter in the delegate, and result. Of course, The disadvantage of this is that if the anonymous method is too long, the readability of the program will be reduced, so generally few people do so, here is a method for reference.

A wise reader must think, since you can use a field to pass in a variable, of course, you can also use the field out of the variable, for example, in the above two examples we see that the results are written in a variable called result (highlighted place), we directly access the variable can not get the results of the calculation?

This has a fatal problem: since it is asynchronous execution, how does the main thread know when the threading completes the calculation? For example, in the last two examples, our thread sleeps for 2000 milliseconds before it is computed, so if the main thread accesses result before it completes the calculation, Can only get a 0 value. So we have the following series of solutions.

Need to pass parameters and return parameters

Just now that the main thread needs to know when the child thread is performing, you can use the Thread.threadstate enumeration to determine.

When a thread is threadstate==threadstate.stop, it usually shows that the thread has done the work, then the result is available, and if it is not in this state, continue with the other work, or wait for a while, and try again. If you need to wait for more than one child thread to return, and need to use their results for asynchronous computation, which is called thread synchronization, we introduce another method I recommend, can customize the number of parameters, and return data, but also relatively convenient to use

asynchronous invocation of methods and callbacks using delegates

First we want to define a method that requires an asynchronous call as a delegate, and then use BeginInvoke to invoke it asynchronously, the first argument of BeginInvoke is the diameter, and the second is the method of calling when the thread finishes executing.

The following is a reference fragment:

Delegate double Calculatemethod (double diameter);

Static Calculatemethod Calcmethod;

Double result = 0;

static void Main (string[] args)

{

Calcmethod = new Calculatemethod (Calculate);

Calcmethod.begininvoke (5, New AsyncCallback (taskfinished), null);

}

///

Functions called by the thread

///

public static double Calculate (double diameter)

{

return diameter * MATH.PI;

}

///

Function of callback after thread completes

///

public static void taskfinished (IAsyncResult result)

{

Result=calcmethod.endinvoke (result);

}

Example 5

Note that after the thread has finished executing the method taskfinished, we use the EndInvoke to get the return value of the function.

Thread pool

Although the thread is a good thing, but also a large resource consumption, many times, we need to use multithreading, but do not want the number of threads too much, this is the role of the thread pool. NET provides us with the ready-made thread pool ThreadPool, his use is as follows:

The following is a reference fragment:

WaitCallback w = new WaitCallback (Calculate);

ThreadPool.QueueUserWorkItem (W, 1.0);

ThreadPool.QueueUserWorkItem (w, 2.0);

ThreadPool.QueueUserWorkItem (w, 3.0);

ThreadPool.QueueUserWorkItem (W, 4.0);

public static void Calculate (double diameter)

{

return diameter * MATH.PI;

}

Example 6

First you define a WaitCallback delegate, and the WaitCallback format is void WaitCallback (object state), which means your method must conform to this format, then call QueueUserWorkItem, Add this task to the thread pool, and when the county has a free line, it will dispatch and run your code.

Each process has a thread pool, the default size of the thread pool is 25, and we can set its maximum value by SetMaxThreads method.

[note] Because each process has only one thread pool, if the thread pool is used in the IIS process or in the process of SQL Server, and you need to set the maximum capacity of the thread pool to affect the IIS process or the SQL process, you should be particularly cautious in both cases.

Control rights

In the conversation with everyone I found that all accustomed to the object-oriented thinking of colleagues, always in the context of multi-threaded execution is very disturbing, for example 5, the main program started the child thread execution calculate method, after the completion of the callback taskfinished, if the main thread ID is 1, The child thread ID is 2, so calculate is definitely executing in the id=2 thread, what about his callback function taskfinished? It is also done in the id=2 thread context, and it is not usually a problem to try to output the thread ID, but when we need to use a child thread in WinForm programming, we will be able to cause problems, which we'll talk about here.

The particularity of multithreaded programming of form program

When we modify the callback code of example 5 to move into WinForm, we can see the problem.

The following is a reference fragment:

public static void taskfinished (IAsyncResult result)

{

Result=calcmethod.endinvoke (result);

This. Textbox1.text=result;

}

The intent of the program is to write a textbox after the thread has finished executing, however, when the program executes to this. Textbox1.text=result was wrong when he was here. Originally WinForm has very strict requirements for threads, except for the threads that create these controls, other threads want to access the controls on WinForm on a cross thread, except for a few special properties. On some versions of the system, XP, for example, handles this problem, and cross-line program Access can be performed, but most Windows systems are not, so if we do need to modify the control properties across threads, or call the control's methods, we must use a method invoke of the control. This method can switch the execution context back to the thread that created the controls, as follows:

The following is a reference fragment:

delegate void Changetext (string result);

public static void taskfinished (IAsyncResult result)

{

Result=calcmethod.endinvoke (result);

This. BeginInvoke (New Changetext (This.textBox1.AppendText), t.result.tostring ())

}

Since the method must be used in the delegate, instead of setting the Text property directly, if you want to set the Text property, you must wrap a method yourself and then connect to the delegate.

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.