Asynchronous Delegates C# Help

A simple way to create a thread is by defining a delegate and invoking the delegate asynchronously. In Chapter 7, “Delegates and Events,” you saw delegates as type-safe references to methods. The Delegate class also supports invoking the methods asynchronously. Behind the scenes, the Delegate class creates a thread that fulfills the task.

The delegate uses a thread pool for asynchronous tasks. Thread pools are discussed later

To demonstrate the asynchronous features of delegates, start with a method that takes a while to complete. The method TakesAWhile () needs at least the number of milliseconds passed with the second argument to finish because of the Thread. Sleep () method

To invoke this method.:from a delegate, a delegate with the same parameter and return types must be defined, as shown by the delegate TakesAWhileDelegate: public delegate int TakesAWhileDelegate(int data, int ms); Now you can use different techniques, invoking the delegate asynchronously and having. the resulreturned

Polling.

One technique is to poll and check if the delegate has already finished its work. The created delegate class provides the method B.eginInvoke ( ), where you can pass the input parameters defined with the delegate type. BeginInvoke () always has two additional parameters of type AsyncCallback and obj ect, which are discussed later. What’s important now is the return type of BeginInvoke ( ) : IAsyncResul t. With IAsyncResul t, you can get information about the delegate, and also verify if the delegate already finished its work, as is done with the IsCompleted property. The main thread of the program continues the while loop as long as the delegate hasn’t completed its work

 

Walt Handle

Another way to wait for the result from the asynchronous delegate is by using the wait handle that is associated with IAsyncResul t.You can access the wait handle with the AsyncWai tHandle property. This property returns an object of type wai tHandle, where you can wait for the delegate thread to finishits work. The method wai tOne () accepts a timeout with the optional first parameter, where you can define the maximum time you want to wait; here it is set to 50 milliseconds. If a timeout occurs, wai tOne () returns with a false and the while loop continues. If the wait is successful, the while loopis exited with a break, and the result is received with the delegate Endlnvoke () method

You can read more information about wait handles later in the synchronization section of this chapter.

Asynchronous Callback

The third version of waiting for the result from the delegate uses an asynchronous callback. With the third parameter of BeginInvoke ( ), you can pass a method that fulfills the requirements of the AsyncCallback delegate. The AsyncCallback delegate defines a parameter of IAsnycResul t and a void return type. Here, the address of the method TakesAWhileCompleted is assigned to the third parameter that fulfills the requirements of the AsyncCallback delegate. With the last parameter, you can pass any object for accessing it from the callback method. It is useful to pass the delegate instance itself, so the callback method can use it to get the result of the asynchronous method. Now the method TakesAWhileCompleted (.) is invoked as soon as the delegate TakesAWhileDelegate has completed its work. There is no need to wait for a result inside the main thread. However, you may
not end the main thread before the work of the delegate threads is finished unless you don’t have a problem with delegate threads stopping when the main thread ends.

The method TakesAWhileCompleted () is defined with the parameter and return type specified by the 1\.syncCallback delegate. The last parameter passed with the BeginInvoke () method can be read vhere using ar . AsyncState. With the TakesAWhileDelegate you can invoke the EndInvoke method toget the result.

Instead of defining a separate method and passing it to the Beginlnvoke () method, Lambda expressions can be used. The parameter ar is of type IAsyncResul t. With the implementation, there is no need to assign a value to the last parameter of the Beginlnvoke () method because the Lambda expression can ‘directly access variable dl that is in the outer scope. However, the implementation block of the Lambda expression is still invoked from the thread of the delegate, which might not be clear immediately when defining the method this way.

You should use Lambda expressions only if the code within is not too big, and the implementation is not required in different places. In such cases, defining a separate method is preferred. Lambda expressions are explained in Chapter 7, “Delegates and Events.”

The programming model and all of these options with asynchronous delegates – polling, wait handles, and asynchronous callbacks – are not only available with delegates. The same programming modelthis is·ftle asynchronous pattern – can be found in various places in the .NET Framework. For example, you can send an HTTP Web request asynchronously with the BeginC<etResponse () method of the HttpWebRequest class. You can send an asynchronous request to the database with the
BeginExecuteReader () of the SqlCommandclass. The paramesers are similar to those of the Beginlnvoke () class of the ?elegate, and you can use the same mechanisms to get the result.

HttpWebRequest is covered in c#, “Accessing’the Internet,” and SqlCommandis discussed

Instead of using the delegate for creating threads, you can create threads with the Thread class, which is covered in”the next section.

Instead of examining if the delegate is completed, you can also just invoke the Endlnvoke () method of the delegate type after you are finished with the work that can be done by the main thread. Endlnvoke () itself waits until the delegate has completed its work.

Capture

 Walt Handle

Another way to wait for the result from the asynchronous delegate is by using the wait handle that is associated with IAsyncResul t.You can access the wait handle with the AsyncWai tHandle property. This property returns an object of type wai tHandle, where you can wait for the delegate thread to finish its work. The method wai tOne () accepts a timeout with the optional first parameter, where you can define the maximum time you want to wait; here it is set to 50 milliseconds. If a timeout occurs, wai tOne () returns with a false and the while loop continues. If the wait is successful, the while loop is exited with a break, and the result is received with the delegate Endlnvoke () method.

You can read more information about wait handles later in the synchronization section of this chapter.

Asynchronous Callback

The third version of waiting for the result from the delegate uses an asynchronous callback. With the
third parameter of BeginInvoke ( ), you can pass a method that fulfills the requirements of the
AsyncCallback delegate. The AsyncCallback delegate defines a parameter of IAsnycResul t and a
void return type. Here, the address of the method TakesAWhileCompleted is assigned to the third parameter that fulfills the requirements of the AsyncCallback delegate. With the last parameter, you can pass any object for accessing it from the callback method. It is useful to pass the delegate instance itself, so the callback method can use it to get the result of the asynchronous method. Now the method TakesAWhileCompleted (.) is invoked as soon as the delegate TakesAWhileDelegate has completed its work. There is no need to wait for a result inside the main thread. However, you may not end the main thread before the work of the delegate threads is finished unless you don’t have a problem with delegate threads stopping when the main thread ends.

The method TakesAWhileCompleted () is defined with the parameter and return type specified by the 1\.syncCallback delegate. The last parameter passed with the BeginInvoke () method can be read here using ar . AsyncState. With the TakesAWhileDelegate you can invoke the EndInvoke method to get the result.

Instead of defining a separate method and passing it to the Beginlnvoke () method, Lambda expressions can be used. The parameter ar is of type IAsyncResul t. With the implementation, there is no need to assign a value to the last parameter of the Beginlnvoke () method because the Lambda expression can ‘directly access variable dl that is in the outer scope. However, the implementation block of the Lambda expression is still invoked from the thread of the delegate, which might not be clear immediately when defining the method this way.

You should use Lambda expressions only if the code within is not too big, and the implementation is not required in different places. In such cases, defining a separate method is preferred. Lambda expressions
are explained in Chapter 7, “Delegates and Events.”

The programming model and all of these options with asynchronous delegates – polling, wait handles, and asynchronous callbacks – are not only available with delegates. The same programming modelthis
is·ftle asynchronous pattern – can be found in various places in the .NET Framework. For example, you can send an HTTP Web request asynchronously with the BeginC<etResponse () method of the
HttpWebRequest class. You can send an asynchronous request to the database with the BeginExecuteReader () of the SqlCommandclass. The paramesers are similar to those of the Beginlnvoke () class of the ?elegate, and you can use the same mechanisms to get the result.

HttpWebRequest is covered in Chapter 41, “Accessing’the Internet,” and SqlCommandis discussed

Instead of using the delegate for creating threads, you can create threads with the Thread class, which is covered in”the next section

Posted on November 2, 2015 in Threading and Synchronization

Share the Story

Back to Top