Asynchronous programming model APM (2)

Source: Internet
Author: User

Use APM to perform computing-restricted asynchronous operations

We can call any method through APM, but first, we need to define a method with the same signature as the method we want to call. Take the method of calculating the sum of 1 to n as an example (this is a computation intensive task that does not perform any I/O operations ).

Private Static uint64 sum (uint64 N)
{
Uint64 sum = 0;
For (uint64 I = 1; I <= N; I ++)
{
Checked
{
// The checked code is used here to throw an exception when the result sum does not match the type uint64
Sum + = I;
}
}
Return sum;
}

If n is very large, the sum method takes a long time. Therefore, we want to execute this method asynchronously. To do this, first define a delegate with the same signature as the method (SUM) that you want to call asynchronously.

internal delegate UInt64 SumDelegate(UInt64 n);

C # The Compiler compiles the previous line of code into a class definition. Its Logic format is as follows:

internal sealed class SumDelegate : MulticastDelegate
{
public SumDelegate(Object object, IntPtr method);
public UInt64 Invoke(UInt64 n);
public IAsyncResult BeginInvoke(UInt64 n, AsyncCallback callback, Object object);
public UInt64 EndInvoke(IAsyncResult result);
}

When a delegate is defined in C # source code, the compiler usually generates a class containing the begininvoke and endinvoke methods. The begininvoke method has the same parameters as the delegate definition, and two additional parameters asynccallback and object are added. All begininvoke Methods return an iasyncresult object. The endinvoke method has only one parameter, iasyncresult. The endinvoke method returns the data type returned by the delegate signature. The following code demonstrates how to use the method callback aggregation technique to asynchronously call the sum method:

Public static void main ()
{
// Initialize a delegate variable to reference the method we want to call Asynchronously
Sumdelegate = sum;

// Call the method of using the thread pool thread
Sumdelegate. begininvoke( 100000000, sumisdone, sumdelegate );

// Execute some other code here

// Suspends the main thread for demonstration
Console. Readline ();
}

Private Static void sumisdone (iasyncresult AR)
{
// Extract the sumdelegate object from the iasyncresult object
Sumdelegate = (sumdelegate) Ar. asyncstate;

// Obtain the result
Uint64 sum = sumdelegate. endinvoke (AR );

// Display the result
Console. writeline ("sum = {0}", sum );
}

The begininvoke method adds operations to the queue of the thread pool. The threads in the thread pool will be awakened, work items will be taken out of the queue, and then the operation restricted by calculation will be called (sum in this example ). Generally, when a thread in the thread pool returns from the execution method, the thread returns to the thread pool. However, the begininvoke method uses the name of a method (sumisdone) as its penultimate parameter. Therefore, when the sum method returns, the thread in the thread pool will not return to the thread pool. Instead, it will call the sumisdone method. That is to say, the callback method is called when the operation restricted by computing is completed.

APM and exceptions

Whenever you call the beginxxx method, it may throw an exception. Windows will tell the application that the asynchronous operation has been completed incorrectly. To achieve this, Windows will send a notification to the CLR thread pool. Finally, our code aggregates the operation results by calling the endxxx method. Generally, the endxxx method returns the operation result to the code, but if the operation fails, the endxxx method throws an exception. Therefore, we should consider handling exceptions when calling the endxxx method. As follows:

Private Static void sumisdone (iasyncresult AR)
{
// Extract the sumdelegate object from the iasyncresult object
Sumdelegate = (sumdelegate) Ar. asyncstate;

Try
{
Uint64 sum = sumdelegate. endinvoke (AR );
Console. writeline ("sum = {0}", sum );
}
Catch (overflowexception)
{
Console. writeline ("sum can't be shown: number is too big .");
}
}

 

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.