C # uses the BeginInvoke and EndInvoke methods of the delegate (Delegate) to manipulate threads

Source: Internet
Author: User

C # uses the BeginInvoke and EndInvoke methods of the delegate (Delegate) to manipulate threads
C # 2011-03-05 13:06:24 read 19 Comments 0 font Size: Big Small Subscription

Manipulating threads with the BeginInvoke and EndInvoke methods of the delegate (Delegate)

There are many ways to use threading in C #, and the BeginInvoke and EndInvoke methods of using delegates are one of them.

The BeginInvoke method can use threads to asynchronously execute the method that the delegate points to.
The return value of the method is then obtained by the EndInvoke method (the return value of the EndInvoke method is the return value of the called method), or the method has been successfully called. There are four ways to get the return value from the EndInvoke method.

1, use the EndInvoke method directly to get the return value

When using BeginInvoke to invoke a method asynchronously, the EndInvoke method will block until the method is executed if the method is not finished. As shown in the following code:
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 ("Mission Accomplished");
return n;
}

Private delegate int newtaskdelegate (int ms);
static void Main (string[] args)
{
Newtaskdelegate task = NewTask;
IAsyncResult AsyncResult = task. BeginInvoke (+, NULL, NULL); EndInvoke method will be blocked for 2 seconds
int result = task. EndInvoke (AsyncResult);
Console.WriteLine (result);
}
}
}

After running the above program, the program does not output the final result (a random integer) until 2 seconds since the NewTask method is delayed by sleep by 2 seconds. If you do not call the EndInvoke method, the program exits immediately, because the thread created with BeginInvoke is a background thread, and once all of the foreground threads have exited (where the main thread is a foreground thread), the thread will end regardless of whether the background thread finishes executing. and exit the program. Detailed information about the foreground and background threads will be explained in a later section.

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

Thread.Sleep (10000);

To delay the main method for 10 seconds, execute the following code, then press CTRL+F5 to run the program, open Enterprise Manager, observe the number of threads in the current program, assume that the number of threads is 4, and after 10 seconds, the number of threads increases to 5. This is because when the BeginInvoke method is called, a thread is created to execute the NewTask method asynchronously, so the threads add a

2, use the IAsyncResult AsyncResult property to determine whether the asynchronous call is complete


Although the method above can implement asynchronous invocation well, when calling the EndInvoke method to get the result of the call, the whole program is just as dead, so the user doesn't feel too good, so we can use asyncresult to determine whether the asynchronous call is complete and display some hints. Doing so can increase the user experience. The code is as follows:
static void Main (string[] args)
{
Newtaskdelegate task = NewTask;
IAsyncResult AsyncResult = task. BeginInvoke (+, NULL, NULL);
while (!asyncresult.iscompleted)
{
Console.Write ("*");
Thread.Sleep (100);
}

Because the asynchronous call is complete, EndInvoke returns the result immediately
int result = task. EndInvoke (AsyncResult);
Console.WriteLine (result);
}


Use the WaitOne method to wait for asynchronous method execution to complete


Using the WaitOne method is another way to determine whether an asynchronous call is complete. The code is as follows:
static void Main (string[] args)
{
Newtaskdelegate task = NewTask;
IAsyncResult AsyncResult = task. BeginInvoke (+, NULL, NULL);
while (!asyncresult.asyncwaithandle.waitone (+, False))
{Console.Write ("*");}
int result = task. EndInvoke (AsyncResult);
Console.WriteLine (result);
}
The first parameter of WaitOne represents the number of milliseconds to wait, and within a specified time, the WaitOne method waits until the asynchronous call is complete and notifies the WaitOne method to return True. When the asynchronous call is still not completed after waiting for the specified time, the WaitOne method returns False if the specified time is 0, indicating that no wait, if 1, means that the asynchronous call is completed forever.

Returning results using a callback method the methods described above are actually only equivalent to one method. Although these methods can successfully return the results, but also to give the user some hints, but in this process, the whole program is like dead (if the reader in the GUI program is very obvious to use these methods), in order to call the process, the program can still do other work, you must use the way of asynchronous calls. Below we use GUI program to write an example, the code is as follows:
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 as MyMethod). EndInvoke (AsyncResult). ToString ();
}

private void Button1_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 previous part of the BeginInvoke parameter, and if there are no parameters, the BeginInvoke will have only two parameters). The first parameter is the callback method delegate type, which has only one parameter, which is IAsyncResult, as shown in the Methodcompleted method. The Methodcompleted method is called automatically when the method methods are executed. The second parameter of BeginInvoke needs to pass some values to the Methodcompleted method, which can generally pass the delegate of the called method, such as my in the code above. This value can be obtained using the IAsyncResult.AsyncState property.

Because the above code accesses a textbox on the form asynchronously, you need to press CTRL+F5 to run the program (you cannot run the program directly by pressing F5, otherwise you cannot access the textbox in other threads, for if the GUI component is accessed in another thread, Detailed in the following sections). And put some other visual controls on the form, but after clicking on Button1, the other controls can still be used, as if nothing happened, and after 10 seconds, 100 will be output in TextBox1.

C # uses the BeginInvoke and EndInvoke methods of the delegate (Delegate) to manipulate threads

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.