) C # thread Series Lectures (1): BeginInvoke and EndInvoke Methods

Source: Internet
Author: User

Development language: C #3.0

IDE: Visual Studio 2008

This series of tutorials mainly includes the following content:

1. BeginInvoke and EndInvoke Methods

2. Thread class

3. Thread Pool

4. Thread Synchronization Basics

5. deadlock

6. 7 methods of Thread Synchronization

7. How to access GUI components in a thread

I. Thread Overview

In the operating system, a process must contain at least one thread. In some cases, you must execute multiple tasks simultaneously in the same process or provide program performance, the task to be executed is divided into multiple subtasks for execution. This requires that multiple threads be enabled in the same process. We use C # To write an application (either on the console or on the desktop), run the program, and open windows Task Manager, then we can see the number of threads in this application, as shown in.

If the task manager does not have the "thread count" column, choose View> Select column to display the "thread count" column. It can be seen that almost all processes have more than two threads. It can be seen that the thread is one of the important means to provide application performance, especially on multi-core CPU machines.

2. Use a Delegate)BeginInvokeAnd EndInvokeMethod operation thread

There are many ways to use threads in C #. One of them is to use the delegate BeginInvoke and EndInvoke methods. The BeginInvoke method can use threads to asynchronously execute the methods pointed to by the delegate. Then obtain the return value of the method through the EndInvoke method (the return value of the EndInvoke method is the return value of the called method), or determine whether the method has been successfully called. We can obtain the return value from the EndInvoke method in four ways.

3. directly use EndInvokeMethod to obtain the returned value

When BeginInvoke is used to call a method asynchronously, if the method is not executed, the EndInvoke method will be blocked until the method is executed. The following code is used:

Using System;
Using System. Collections. Generic;
Using System. Linq;
Using System. Text;
Using System. Threading;

Namespace MyThread
{
Class Program
{
Private static int newTask (int MS)
{
Console. WriteLine ("task start ");
Thread. Sleep (MS );
Random random = new Random ();
Int n = random. Next (10000 );
Console. WriteLine ("task completed ");
Return n;
}

Private delegate int NewTaskDelegate (int MS );


Static void Main (string [] args)
{
NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task. begininvoke( 2000, null, null );

// The EndInvoke method will be blocked for 2 seconds
Int result = task. EndInvoke (asyncResult );
Console. WriteLine (result );
}
}
}

After running the above program, because the newTask method delay by Sleep for 2 seconds, the program will not output the final result (a random integer) until 2 seconds ). If you do not call the EndInvoke method, the program will immediately exit because all the threads created using BeginInvoke are background threads, this kind of thread will end the thread and exit the program no matter whether or not the background thread is finished after all foreground threads exit (the main thread is a foreground thread. The details of front-end and back-end threads are described in the following sections.

Readers can use the above program to do the following experiments. First, add the following code at the beginning of the Main method:

Thread. Sleep (10000 );

To delay the Main method by 10 seconds and then execute the following code, press Ctrl + F5 to run the program, open the Enterprise Manager, and observe the number of threads of the current program. Assume that the number of threads is 4, after 10 seconds, the number of threads will increase to 5 because a thread will be created to asynchronously execute the newTask method when the BeginInvoke method is called. Therefore, a thread will be added.

Iv. Use the IAsyncResult asyncResult attribute to determine whether the asynchronous call is complete

Although the above method can be used to implement asynchronous calls, when the EndInvoke method is called to obtain the call result, the whole program is like dead, so the user's feeling is not very good. Therefore, we can use asyncResult to determine whether the asynchronous call is complete and display some prompts. This will increase the user experience. The Code is as follows:

Static void Main (string [] args)
{
NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task. begininvoke( 2000, null, null );

While (! AsyncResult. IsCompleted)
{
Console. Write ("*");
Thread. Sleep (100 );
}
// Because the asynchronous call is complete, EndInvoke immediately returns the result
Int result = task. EndInvoke (asyncResult );
Console. WriteLine (result );
}

Shows the execution result of the above Code.

Because it is asynchronous, "*" may be output before "task start", as shown in.


5. Use the WaitOne method to wait for the Asynchronous Method to be executed.

The WaitOne method is another method used to determine whether the asynchronous call is complete. The Code is as follows:

Static void Main (string [] args)
{
NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task. begininvoke( 2000, null, null );

While (! AsyncResult. AsyncWaitHandle. WaitOne (100, false ))
{
Console. Write ("*");
}

Int result = task. EndInvoke (asyncResult );
Console. WriteLine (result );
}

The first parameter of WaitOne indicates the number of milliseconds to wait. within the specified time, the WaitOne method will wait until the asynchronous call is completed and a notification is sent. The WaitOne method returns true. When the asynchronous call is not completed after the specified time, the WaitOne method returns false. If the specified time is 0, it means no waiting. If it is-1, it means waiting forever until the asynchronous call is completed.

6. Return results using callback

The methods described above are actually only one method. Although these methods can successfully return results, you can also give some prompts, but in this process, the whole program is like dead (if the reader uses these methods in the GUI program, it will be very obvious). If you want to call the program, the program can still do other work normally, you must use the asynchronous call method. The following code uses a GUI program to compile an example:

Private delegate int MyMethod ();
Private int method ()
{
Thread. Sleep (10000 );
Return 100;
}
Private void MethodCompleted (IAsyncResult asyncResult)
{
If (asyncResult = null) return;
TextBox1.Text = (asyncResult. AsyncState
MyMethod). EndInvoke (asyncResult). ToString ();
}

Private void button#click (object sender, EventArgs e)
{

MyMethod my = method;
IAsyncResult asyncResult = my. BeginInvoke (MethodCompleted, my );
}

Note that the last two parameters of the BeginInvoke method are used here (if the called method contains parameters, these parameters will be used as the first part of the BeginInvoke parameter. If there is no parameter, beginInvoke only has two parameters ). The first parameter is the delegate type of the callback method. This delegate has only one parameter, IAsyncResult, as shown in MethodCompleted. After the method is executed, the system automatically calls the MethodCompleted method. The second parameter of BeginInvoke needs to pass some values to the MethodCompleted method. Generally, you can pass the delegate of the called method, as shown in my in the code above. This value can be obtained using the IAsyncResult. AsyncState attribute.

Because the above Code accesses a textbox on the form asynchronously, You need to press ctrl + f5 to run the program (you cannot directly press F5 to run the program, otherwise, the textbox cannot be accessed in other threads. For details about accessing GUI components in other threads, see the following section ). And put some other visual controls on the form. However, after clicking button1, other controls can still be used, just as nothing has happened. After 10 seconds, output 100 in textbox1.

VII. BeginXXX of other componentsAnd EndXXXMethod

Other. net components also have methods similar to BeginInvoke and EndInvoke, such as the BeginGetResponse and EndGetResponse methods of the System. Net. HttpWebRequest class. Below is an example of using these two methods:

Private void requestCompleted (IAsyncResult asyncResult)
{
If (asyncResult = null) return;
System. Net. HttpWebRequest hwr = asyncResult. AsyncState as System. Net. HttpWebRequest;
System. Net. HttpWebResponse response =
(System. Net. HttpWebResponse) hwr. EndGetResponse (asyncResult );
System. IO. StreamReader sr = new
System. IO. StreamReader (response. GetResponseStream ());
TextBox1.Text = sr. ReadToEnd ();
}
Private delegate System. Net. HttpWebResponse RequestDelegate (System. Net. HttpWebRequest request );

Private void button#click (object sender, EventArgs e)
{
System. Net. HttpWebRequest request =
(System. Net. HttpWebRequest) System. Net. WebRequest. Create ("http://www.cnblogs.com ");
IAsyncResult asyncResult = request. BeginGetResponse (requestCompleted, request );
}

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.