C # asynchronous use of delegation

Source: Internet
Author: User

CLR maintains a thread pool for each process. It is empty at the beginning. But when a thread is created and used by the process, and its execution is completed, it is not destroyed, but added to the thread pool of the process. When the process needs a thread again, it will reuse the thread in the pool, which saves a lot of time.
Thread complexity:
Although the concept of Multithreading is simple, it is difficult to make all the details correct. The following needs to be considered:
1> there are only a few built-in mechanisms for inter-thread communication, so using memory is the simplest mechanism, because the memory is visible to and accessible to all threads in the same process.
2> thread coordination, the creation of threads is very simple, but they still need to be coordinated. For example, a thread can continue its own execution only after one or more other threads have completed the execution.
3> Use of synchronization resources. Because all threads in the same process share the memory and resources of the process, different threads must not be able to access and change them at the same time, avoid inconsistent resource/memory statuses.
When creating a complex multi-threaded system, you can use system. classes and types in the threading namespace, including the Thread class and others such as mutex, semaphore, and monitor ). they are used to synchronize resources. these concepts are relatively low-level and difficult to understand. It is best to find some operating system principles.

References.
You can add powerful multi-threaded functions to your program through two simple technologies: asynchronous delegation and timer (asynchronous delegates and timers ), for most programs, this is the only thread technology you may need.
C # has a very easy-to-use mechanism for Asynchronous Method execution: delegates (delegate ). The delegate object has a call list. If there is only one method in the list, it can be executed asynchronously. The ininvoke and endinvoke methods of the delegate class are for this purpose. The procedure is as follows:
1> when the ininvoke () method of the delegate object is called, it starts to execute the method pointed to by the delegate in a thread from the thread pool, and then immediately returns to the initial thread, the first thread will continue to execute the following code. at the same time, the thread to be executed is also executed in parallel.
2> when your program wants to extract the results of the asynchronous execution method, you can first check the iscompleted attribute returned by the begininvoke () method, or call endinvoke () wait until the delegate execution is complete.
Three standard usage modes:
1> wait-until-done waits until the completion mode. After an Asynchronous Method is generated (beginnvoke (), the initial thread performs some other processing, it will be suspended and wait until the end of the Asynchronous Method to continue execution. different from the synchronous method, the initial thread cannot perform any other processing once the synchronous method is called. The control is completely transferred to the called method.
2> in polling round-robin mode, the initial thread periodically checks whether the new thread has completed the execution. If not, continue other processing.
3> In the callback mode, the initial thread does not wait or check whether the egg thread has completed the execution. Instead, when the method referenced by the delegate is completed in the spawned thread, the subthread calls a callback method. This method processes the call results of an Asynchronous Method before calling endinvoke.
Note: The original thread can be called a parent thread, and the thread generated by it (spawn) can be called a subthread. Some information about begininvoke () must be known:
1> when begininvoke is called, the parameter list includes the following actual parameters:
A: The parameter B required by the function to be referenced by the delegate. The other two parameters are callback and state;
2> begininvoke () extracts a thread from the thread pool and starts the referenced method to run in the new thread.
3> begininvoke () is returned to the calling thread as an object that implements the iasyncresult interface. The reference of this interface contains the execution status information of the currently executed Asynchronous Method.

Continue execution after the initial thread.
Consider the idea That Ajax, which is widely advocated, is just like this.
The endinvoke () method is used to extract the return value of an asynchronous method call and is used by the thread to release resources. Endinvoke has the following features:
1> it uses a reference pointing to iasyncresult as the parameter. iasyncresult is the return value of begininvoke and finds the thread referenced by it (iasyncresult.
2> If the thread in the thread pool has exited, endinvoke does the following:
A: Clear the exited threads and release their occupied resources. B: Find the return value of the corresponding method and use it as its own return value.
If the thread in the thread pool is still running when the endinvoke is called, the caller thread (parent thread) stops and waits for it until it is cleared and the return value is returned. Because endinvoke cleans up the generated threads, you must ensure that endinvoke () is called for each begininvoke () (if you do not want to disclose resources );
3> If an Asynchronous Method triggers an exception, the exception is triggered when endinvoke () is called. endinvoke provides all outputs from Asynchronous methods, including the ref and out parameters. if the delegate methods have the ref and out parameters, they must appear in the parameters of the endinvoke () method and prior to the iasyncresult location: Delegate. endinvoke (Out somepara, iasyncresult );
Wait till the completion mode:
Namespace waitutildone
{
Public Delegate string asycdelegate (out string outarg, string inarg); // delegate Definition
Class Program
{

Static void main (string [] ARGs)
{
Asycdelegate myasycdelegate = (asycdelegate) asyncworker. asyncmethod; // defines a delegate member variable. The simple form is used here.
String fromasyncmethrod;

Iasyncresult iasyncrsl = myasycdelegate. begininvoke (Out fromasyncmethrod, "toasycmethod", null, null );


// In the main thread... other things can be done at this time thread. Sleep (2000 );

// The Master thread takes 2 seconds to rest

String returnstrfromasyncmethod = myasycdelegate. endinvoke (Out fromasyncmethrod, iasyncrsl );
System. Console. writeline ("the string return from asyncmethod is {0}", returnstrfromasyncmethod );
System. Console. writeline ("The fromasyncmethod is: {0}", fromasyncmethrod );
System. Console. Readline ();
}
}

Class asyncworker {

Public static string asyncmethod (out string fromthismethod, string tothismethod ){
System. Console. writeline ("<enter the asyncmethod! ");
Fromthismethod = "string form asyncwork. asyncmehod as a out parameter ";

System. Console. writeline ("parameter passed into this Asynchronous Method: {0}", tothismethod );
Thread. Sleep (6000); // This method will block the thread running this method for six seconds

System. Console. writeline ("End the asyncmehod> ");

Return "returnvaluefromasyncmethod! ";
}

}
}

! Iasyncresult: it is an indispensable part of begininvoke () and endinvoke. the begininvoke method returns an object reference of the asyncresult type. This class of asyncresult implements the isyncresult interface. asyncreslut indicates the state of the Asynchronous Method. You need to know the following important features for this class:
1> when the begininvoke method of the delegate object is called, The system creates an instance of this class and returns the reference of this object to the isyncresult interface.
2> the asyncresult object contains an asyncdelegate attribute, which returns a reference to the delegate that calls the asynchronous method. This attribute is the asyncresult attribute, not the iayncresult interface attribute.
3> the iscompleted attribute returns a Boolean value indicating whether the asynchronous method has been executed.
4> the asyncstate attribute returns an object reference, which will be used as a reference returned by the call parameter of the begininvoke method. It is used in the callback mode.
@ Round robin mode:
In polling mode, after the original thread calls an asynchronous method, it performs some additional work and periodically checks the isompleted of the object referred to by iasyncresult to check whether the Asynchronous Method is executed, if this is done, the endinvoke is called and the execution is continued. Otherwise, some other work is performed and the check is continued.:

Using system;
Using system. Collections. Generic;

Using system. text;
Using system. Threading;

Namespace poolingpattern
{
Public Delegate string asyncdelegate ();
Class Program
{
Static string asycmethod (){

System. Console. writeline ("<enter the asyncmethod .....");

Thread. Sleep (3000 );

System. Console. writeline ("... end the asyncmethod> ");
Return "returnvaluefromtheasyncmethod ";
}

Static void main (string [] ARGs)
{
Asyncdelegate myasyncdele = new asyncdelegate (asycmethod); // construct a delegate

System. Console. writeline ("calling Asynchronous Method in main method ");
Iasyncresult iasyncrslt = myasyncdele. begininvoke (null, null );

While (! Iasyncrslt. iscompleted ){
System. Console. writeline ("checking in the main thread->:... the asynchronous call method is still not completed ...");
For (long I = 0; I <= 100000000; I ++)
; // Do something of your own. Here is the CPU consumption.
} // The Asynchronous Method should have been completed at the end of the Round-Robin.

/* Now the asynchronous execution result can be mentioned */
String strfromasyncmethod = myasyncdele. endinvoke (iasyncrslt );
System. Console. writeline ("result returned by the Asynchronous Method: {0}", strfromasyncmethod );

System. Console. writeline ("the main method ends ");
System. Console. Readline ();

}
}
}
# In the first two modes, when the original thread (the thread that runs the main () method) completes (waiting or polling, extract the Asynchronous Method Results and continue the main thread. Different callback modes: the parent thread does not need to wait or polling after the delegate is asynchronously called. When the Asynchronous Method is executed, the system calls a callback method to process the result of the Asynchronous Method, and call the endinvoke method to release related resources. The last two parameters of the begininvoke method are usage and callback purpose:
The first parameter of the last two parameters of begininvoke is the name of the callback function (the function name can be converted to a delegate !!). The second parameter state is null or a reference to an object that you want to pass to the callback function. You can access this object through the iasyncresult parameter of the method (using its asyncstate attribute. The parameter type must be explicitly converted to a specific type when the object type is used.
@ The callback function signature must be consistent with the asynccallback delegate form. This form requires the callback function to require an iasyncresult type parameter and an empty return value.

Void asynccallback (iasyncresult IAR );
There are multiple ways to provide callback functions to the begininvoke method. Because the callback parameter type in begininvoke is asynccallback delegate type, you can directly provide a function name or construct a delegate object first. Remember that the name of a function in a specific format can always be implicitly converted into a delegate by the compiler. The following are my little exercises:
Using system;
Using system. Collections. Generic;
Using system. text;
Using system. Threading;
Using system. runtime. remoting. messaging;
Namespace callbackpattern
{
Class Program
{
Static void callbackmethod (iasyncresult asyncrslt ){
System. Console. writeline ("<... enter the callbackmethod ");
System. Console. writeline ("This callback function is called after the Asynchronous Method is executed ");

Asyncresult myasynresult = (asyncresult) asyncrslt;
Eventhandler asyncdele = (eventhandler) myasynresult. asyncdelegate;
Asyncdele. endinvoke (asyncrslt); // For details about Resource Recycling, see the following description.

System. Console. writeline ("End the callbackmethod...> ");
}

Static void myasyncmethod (Object source, system. eventargs evtargs ){
System. Console. writeline ("entering the asynchronous method call area ");
Thread. Sleep (5000 );

System. Console. writeline ("calling region for ending asynchronous methods");
}
Static void main (string [] ARGs)
{
System. Console. writeline ("entering the main thread ....");

Eventhandler myasyncdelegate = (eventhandler) myasyncmethod;/* gets lazy and uses the delegate provided by the system. Note that the method name is correct.

Convert to a delegate */
Iasyncresult iasyncrslt = myasyncdelegate. begininvoke (null, null, callbackmethod, null );
// Using implicit conversion is equivalent to the following method:
// Asynccallback mycallback = new asynccallback (callbackmethod );
// Iasyncresult iasyncrslt = myasyncdelegate. begininvoke (null, null, callbackmethod, null );

System. Console. writeline ("the main thread ends, waiting for the callback method to be called .....");
System. Console. Readline ();
}
}
}

** The endinvoke method should be called in the callback method. The return value and out parameters of the asynchronous method should be processed (if any !) To call the endinvoke of An Asynchronous Method

Method you need to have a delegate reference pointing to the asynchronous method, which is in the initial thread, but not in the egg thread. If the begininvoke state parameter is not used to do anything, you can use it to pass the delegate reference to the callback method: iasyncresult IAR = delegate. begininvoke (ARGs, callwhendone, delegate); In the callback function, you can use parameters of the iasyncresult type to obtain the reference of the delegate. Note: The iasyncresult interface actually points to an instance of the asyncresult class. Although the interface does not contain delegate references, the asyncresult class objects hold the delegate references. The asyncresult class is located in the system. runtime. remoting. messaging namespace. When you use the asyncdelegate attribute of the asyncresult instance to obtain the delegate and perform the appropriate transformation. Then you can call the endinvoke method.
Using system. runtime. remoting. messaging; // contains the asyncresult class
Void callwhendone (iasyncresult IAR)
{
Asyncresult AR = (asyncresult) IAR; // converts an interface to an asyncresult instance
MYDEL del = (MYDEL) Ar. asyncdelegate; // obtain the delegate and convert it to the appropriate delegate
Long sum = del. endinvoke (IAR); // call endinvoke
...
}

Now, the asynchronous call of the delegate is complete. It is hard to understand the three main modes, especially the callback mode.

 

 

 

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.