Simply use one of the threads: using the Asynchronous Programming model

Source: Internet
Author: User

. NETFramework's asynchronous programming model essentially uses a thread pool to accomplish asynchronous tasks, asynchronous delegates, HttpWebRequest, and so on, all using asynchronous models.

Here we use asynchronous delegates to illustrate the asynchronous programming model.

First, let's make it clear what issues we need to focus on for multithreading.

"Thread is a code flow in execution," from which we can focus on when the code flow begins to execute, when it ends, how the parameters are passed from the main thread to the child threads, how the child threads return results to the main thread?

Question 1: When does a child thread start executing in the asynchronous programming model?

For asynchronous programming models, use BEGINXXX to start the execution of threads.

Let's start with an example (from the C # Advanced Programming (7th Edition)).

Pulic delegate int testmethoddelegate (int data,int ms);

static int TestMethod (int data,int ms)

{

Console.WriteLine ("TestMethod started.");

Thread.Sleep (MS);

Console.WriteLine ("TestMethod completed.");

return data++;

}

Static Main ()

{

Testmethoddelegate Dl=testmethod;

IAsyncResult Ar=dl. BeginInvoke (1,3000,null,null);

Where the 1,3000 corresponds to the two parameters of the delegate, the arguments for the next two null positions are two fixed arguments, which are used when the asynchronous callback is left (later).

}

Question 2: When does the child thread end in the asynchronous programming model ?

In fact, this problem is not a problem for a single threaded procedure with only one main thread, because the execution of the last line of the method is completed during the execution of the code.

But in multi-threading, because the main thread has a subordinate relationship with the child thread, plus the thread and the foreground thread and the background threads, so that the end time of the child thread needs to be judged, the rule is as follows.

(1). If the child thread is a background thread, the child thread ends, regardless of whether the child thread has finished executing.

(2). If the child thread is a pre-strong thread, the child thread will continue to execute until the end of the thread.

PS: Because threads inside the thread pool are all background threads, there is only a 1th case in the asynchronous programming model.

So the question is: if the child thread is a background thread, and the child thread is processing time very long, then the thread will shut down when it is processed to the last code, and the processing logic of the child thread will go wrong.

How can we prevent such a problem from happening?

Intuitively, waiting for a child thread to finish in the main thread is a viable option, and to implement this scenario, at least we need to know if the child thread has finished executing?

In the asynchronous programming model, we can use the polling (Polling), wait handle (Waithandler), EndInvoke () method to achieve this effect.

Method 1: Polling (Polling)

We rewrite the main () method as follows:

Static Main ()

{

Testmethoddelegate Dl=testmethod;

IAsyncResult Ar=dl. BeginInvoke (1,3000,null,null);

While (!ar. iscompleted)

{

Do something

}

When this is done, the child threads have been executed.

}

Method 2: Wait handle (Waithandler)

Let's rewrite the main () method again.

Static Main ()

{

Testmethoddelegate Dl=testmethod;

IAsyncResult Ar=dl. BeginInvoke (1,3000,null,null);

while (true)

{

if (AR. Asyncwaithandler.waitone (50,false))//Waits 50 milliseconds for each wait, then determines whether the child thread is complete, or break if it is completed.

{

When this is done, the child threads have been executed.

Break

}

}

Main thread ....

}

Method 3:endinvoke () method

Use the main () method again:

Static Main ()

{

Testmethoddelegate Dl=testmethod;

IAsyncResult Ar=dl. BeginInvoke (1,3000,null,null);

Ar. EndInvoke ();//Will wait until the delegate method executes, in fact, it can also be used to return the results of the child thread to the main thread, you can refer to the following question 4.

Main thread ....

}

Question 3: in the asynchronous programming model, How do I pass parameters from the main thread to the slave threads?

We have actually shown this in question 1, and we passed two parameters to the delegate in the BeginInvoke method.

Question 4: In the asynchronous programming model, How do I return results from a child thread to the main thread?

In question 2, we use EndInvoke () to wait for the delegate method to execute, but we can also use this method to get the return value of the child thread.

Static Main ()

{

Testmethoddelegate Dl=testmethod;

IAsyncResult Ar=dl. BeginInvoke (1,3000,null,null);

int Result=ar. EndInvoke ();//Gets the return value, the return value type here is int, which is the return value type defined by the delegate.

Main thread ....

}

Issue 5: Asynchronous callbacks

Asynchronous callbacks are useful, and it should be said that they greatly extend the power of multithreading under an asynchronous model. Why do you say that?

Consider a situation where if the main thread takes 120 seconds to complete execution, the child thread takes 80 seconds, starts with a boot sub-thread at the main thread Cheng Di 90 seconds, the main thread waits for the child thread to end, and finally ends the main thread. Then, the entire main thread takes at least 90+80 seconds to complete execution, and there is obviously a lot of time for the main thread to wait for the child thread. Is there a better way?

If the main thread does not need the return results of the child threads, and there are some separate processing logic (such as cleanup objects, separate processing data, etc.) at the end of the child thread, we can use asynchronous callbacks to solve the problem.

Asynchronous callback: In short, the method that is called after the asynchronous task is completed.

Let's look at an example of an asynchronous callback:

Static Main ()

{

Testmethoddelegate Dl=testmethod;

IAsyncResult Ar=dl. BeginInvoke (1,3000,TESTMETHODCOMPLETED,DL);

Main thread ....

}

Static testmethodcompleted (IAsyncResult ar)

{

Do something

Testmethoddelegate dl= (testmethoddelegate) ar. Aysncstate;

Dl. EndInvoke ();//You can pass the delegate instance in and get the result of the delegate thread here.

}

Here, we focus on the 3rd and 4th parameters of the BeginInvoke method.

The 3rd argument, testmethodcompleted, is the callback method, which is a delegate of type AsyncCallback.

The 4th parameter is the argument passed to the callback method, which can be used with AR in the callback method. AsyncState to get this parameter.

Using a callback method, it is important to note that this method is called from the delegate thread, not from the main path, and is called a normal method call if it is invoked from within the main path.

In addition, if you use lambda expressions you can implement some more concise and elegant.

Static Main ()

{

Testmethoddelegate Dl=testmethod;

Dl. BeginInvoke (1, 3000,

ar=>{

int RESULT=DL. EndInvoke (AR);

Do something

},

NULL);

Main thread ....

}

Here, you do not need to assign a value to the last parameter of the BeginInvoke () method, because the lambda expression can directly access the variable DL outside of the scope. However, the implementation code for the LAMBSA expression is still called from the delegate thread, but it is not obvious.

Simply use one of the threads: using the asynchronous Programming model

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.