Asynchronous Pattern


Now that you have an understanding of how to use threads to perform tasks asynchronously, we ll present another way you can perform tasks asynchronously by using the asynchronous pattern that s available in many of the classes in the .NET Framework. The asynchronous pattern is designed around methods that can potentially block when they perform their operation. Methods that block typically take a long time to perform a task such as writing data to a file or reading data from a network.

Classes that are designed to use the asynchronous pattern for methods that block have a BeginXXX method to start a task and an EndXXX method that completes a task. The XXX portion represents an actual name of the blocking task in the class. For example, in the FileStream class, the Write method can potentially block when writing data to a file. The FileStream class has BeginWrite and EndWrite counterpart methods that use the asynchronous pattern to prevent blocking on an I/O operation.

Note  

You should not mix the use of asynchronous calls with synchronous calls from the same instance of a class in the .NET Framework. For example, do not attempt to perform a FileStream Read synchronous operation while a FileStream BeginRead asynchronous operation is running. Doing so can cause unpredictable behavior in the class at hand.

To use the asynchronous pattern, you must call the BeginXXX method and supply a delegate callback method to the BeginXXX call. When BeginXXX is called, it will complete immediately and the class at hand will run the XXX operation in parallel, which means that your calling application (or calling thread) is free to continue processing other code. Each .NET Framework class internally handles asynchronous processing using threads and other operating system asynchronous mechanisms. The main point to remember here is that all the classes that use the asynchronous pattern do so with the same design from your application s point of view. When an asynchronous operation completes, your supplied delegate method is invoked to process the completed task results. Inside your delegate method, you have to call the EndXXX counterpart method to retrieve the completed task results.

Note  

When your application performs an asynchronous BeginXXX call, you should not call the EndXXX counterpart method using the IAsyncResult value returned from BeginXXX while the call is running asynchronously. If you do so, your EndXXX call will block until the BeginXXX has completed. When your BeginXXX delegate method finally calls EndXXX after the asynchronous operation is completed, an InvalidOperationException will be thrown on the delegate s EndXXX call.

For example, let s describe how to process a Read call asynchronously from the NetworkStream class using the asynchronous pattern. We chose Read because it will typically block when you wait for data to arrive on a network stream. To call Read asynchronously, you must call BeginRead and supply an asynchronous delegate method named AsyncCallback that will be invoked when the BeginRead operation completes. An AsyncCallback method is similar to a thread delegate method, as described earlier in the chapter. However, AsyncCallback requires you to supply an IAsyncResult interface that s used to retrieve the results of a completed asynchronous operation. The following code fragment demonstrates how to design an AsyncCallback method that handles the completion of a BeginRead asynchronous operation from the NetworkStream class we described in Chapter 2.

C#

 voidProcessReceiveResults(IAsyncResultAsyncResult) { NetworkStreamNS=(NetworkStream)AsyncResult.AsyncState; try { intBytesRead=0; BytesRead=NS.EndRead(AsyncResult); if(BytesRead==0) { NS.Close(); return; } } catch(Exceptione) { Console.WriteLine(Failedtoreadnetworkstreamwitherror:  +e.Message); NS.Close(); } } 

Visual Basic .NET

 SharedSubProcessReceiveResults(ByValAsyncResultAsIAsyncResult) DimNSAsNetworkStream=AsyncResult.AsyncState Try DimBytesReadAsInteger=0 BytesRead=NS.EndRead(AsyncResult) If(BytesRead=0)Then NS.Close() ExitSub EndIf CatcheAsException Console.WriteLine("Failedtoreadnetworkstreamwitherror: " _ +e.Message) NS.Close() EndTry EndSub 

The AsyncResult parameter is an input parameter that receives an IAsyncResult object that you have to pass to the EndRead counterpart method. (Alternatively, you can use the IAsyncResult object that s returned from the originating BeginRead call.) Also, IAsyncResult contains an important member variable named AsyncState that contains the state parameter that was passed in the originating BeginRead call. Typically, you ll use the state parameter to pass information that s related to the asynchronous call BeginXXX . For example, in the preceding code fragment, we demonstrated how to pass an instance of the NetworkStream class to the delegate.

Once your delegate method is defined, you can start the asynchronous operation using the delegate method. The following code fragment demonstrates how to use the ProcessReceiveResults delegate to handle the asynchronous result of a BeginRead operation on a network stream:

C#

 AsyncCallbackAsyncReceiveCallback= newAsyncCallback(ProcessReceiveResults); MyNetworkStream.BeginRead(Buffer,0,Buffer.Length, AsyncReceiveCallback,MyNetworkStream); 

Visual Basic .NET

 AsyncReceiveCallbackAsAsyncCallback=_ NewAsyncCallback(AddressOfProcessReceiveResults) MyNetworkStream.BeginRead(Buffer,0,Buffer.Length, AsyncReceiveCallback,Me) 

When a BeginXXX starter method is called, it will complete immediately and return an IAsyncResult object. Your calling program might call the EndXXX counterpart method on the returned IAsyncResult . If the asynchronous operation has not completed, the EndXXX method will block until the operation has completed. Typically, most applications will handle the completed results in the delegate method instead of in the calling program thread. As you can see in the previous code fragment, we did not retrieve the returned IAsyncResult from the BeginRead call. Instead, we allowed our ProcessReceiveResults delegate method to handle the completed results.

In this chapter s downloadable samples, we provide two samples, AsyncNetworkIO and ThreadNetworkIO, that are revisions of the network stream server sample found in Chapter 2. These revised servers are designed to handle multiple network connections and demonstrate how to use the NetworkStream class to perform network I/O asynchronously. AsyncNetworkIO uses the asynchronous pattern, and ThreadNetworkIO uses threads. The original network stream server sample accepted only one connection and processed I/O synchronously on only one connection. Because these applications process I/O asynchronously, they are now capable of handling multiple network connections at the same time.




Network Programming for the Microsoft. NET Framework
Network Programming for the MicrosoftВ® .NET Framework (Pro-Developer)
ISBN: 073561959X
EAN: 2147483647
Year: 2003
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net