Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C# ПІДРУЧНИКИ / c# / MS Press - Msdn Training Programming Net Framework With C#

.pdf
Скачиваний:
194
Добавлен:
12.02.2016
Размер:
16.87 Mб
Скачать

Module 14 (Optional): Threading and Asynchronous Programming

73

 

 

 

!Performance issues can result when a static method in a class calls a static method in the same class.

If these methods are not factored correctly, performance will suffer because there will be a large amount of redundant synchronization. Excessive use of synchronization may negatively affect performance. In addition, it may have a significant negative effect on scalability.

!Be aware of issues with the lock statement (SyncLock in Visual Basic).

It is tempting to use the lock statement to solve all threading problems. However, the System.Threading.Interlocked class is superior for updates that must be made automatically. It executes a single lock prefix if there is no contention.

In a code review, you should look for instances like the one shown in the following example.

lock(this)

{

myField++;

}

!Avoid the need for synchronization if possible.

For high traffic pathways, it is best to avoid synchronization. Sometimes you can adjust the algorithm to tolerate race conditions rather than eliminate them.

74

Module 14 (Optional): Threading and Asynchronous Programming

" Asynchronous Programming in .NET

Topic Objective

To provide an overview of the topics that you will cover in this section.

Lead-in

In this section, we will look at how the .NET Framework enables asynchronous programming.

!Support for Asynchronous Programming in .NET

!Design Pattern for Asynchronous Programming

!Asynchronous File Stream Read Example

!Asynchronous Delegates

*****************************ILLEGAL FOR NON-TRAINER USE******************************

The central idea behind asynchronous programming is to be able to issue method calls to other components and to carry on with other work, without waiting for the operation to complete. The runtime provides rich support for asynchronous programming and handles the details of threading and data exchange.

In this section, you will learn about how the .NET Framework supports asynchronous programming.

Module 14 (Optional): Threading and Asynchronous Programming

75

 

 

 

Support for Asynchronous Programming in .NET

Topic Objective

To provide a high level overview of the .NET Framework support for asynchronous programming.

Lead-in

In addition to support for asynchronous programming in many areas of .NET, the

.NET Framework offers an asynchronous programming design pattern.

!Supported in Many Areas of .NET

#I/O, sockets, networking, remoting, ASP.NET and Web Services, messaging (MSMQ), delegates

!Offers a design pattern for asynchronous programming

#Consistent and type-safe programming model

#User-created classes should conform to this design pattern

*****************************ILLEGAL FOR NON-TRAINER USE******************************

With asynchronous programming in the .NET Framework, you make a call to a

.NET Framework class method while the program continues execution until a specified callback is made. If no callback is specified, the program continues execution until it encounters blocking, polling, or waiting for the call to complete.

For example, a program can call a method which enumerates a large list, while the main program continues to execute. When the enumeration is complete, a callback is made and the program addresses it.

Many areas of the .NET Framework support asynchronous programming, including:

!File IO, Stream IO, Socket IO

!Networking: HTTP, TCP

!Remoting channels (HTTP, TCP) and proxies

!XML Web services created by using ASP.NET

!ASP.NET Web Forms

!Messaging message queues over MSMQ

!Asynchronous delegates

The .NET Framework provides a design pattern that makes asynchronous calls uniform across the different parts of the framework. This pattern is very useful for making complex calls that take a considerable amount of time to complete. User-created classes that support asynchronous calls should conform to this design pattern.

76

Module 14 (Optional): Threading and Asynchronous Programming

Design Pattern for Asynchronous Programming

Topic Objective

To provide details of the asynchronous design pattern.

Lead-in

One of the innovations that is provided by the asynchronous design pattern is that the caller can decide whether a particular call should be asynchronous.

!Caller decides whether to make a synchronous or asynchronous call

#Server may explicitly implement asynchronous methods, or client can use delegate object’s asynchronous support

!Caller does asynchronous operation in two parts

#Call begin method to supply parameters and start operation

-an object implementing IAsyncResult is returned

#When operation is done, call end method to obtain the results

!Caller has several options to know when operation is done

#Callback method - if specified in the begin method call, callback is invoked

#Poll – check IAsyncResult.IsCompleted property

#Call end method – if called before operation is done, automatically waits

#Wait – wait on IAsyncResult.WaitHandle property, can use timeouts

*****************************ILLEGAL FOR NON-TRAINER USE******************************

One of the innovations that is provided by the asynchronous design pattern is that the caller can decide whether a particular call should be asynchronous. You do not need to do additional programming for the called object for it to support asynchronous client calls. The client can make an asynchronous call on another object whose class does not explicitly support such calls by instantiating a delegate object that refers to the object’s method.

The runtime and language compilers encapsulate methods that provide asynchronous operation into delegate classes. The called object can choose to explicitly support asynchronous behavior; either because it can implement asynchronous behavior more efficiently than by using a general architecture, or because the called object is designed to support only asynchronous behavior by its callers. The level of asynchronous support of the called object is up to the object’s author.

However, if an object is to explicitly support asynchronous methods, you should follow the asynchronous design pattern for exposing these methods.

Details of the asynchronous design pattern

In the .NET Framework asynchronous design pattern, the asynchronous operation is split into two logical parts: the part where the client calls a begin operation method and provides input to start the asynchronous operation, and the part where the results of the asynchronous operation are obtained by the client through a call to an end operation method.

Module 14 (Optional): Threading and Asynchronous Programming

77

 

 

 

Beginning the asynchronous operation

In the first part of an asynchronous call, the caller upon invoking the begin operation method can also supply an optional AsyncCallback delegate, in addition to providing the input needed for the operation. This delegate refers to the method to be called when the asynchronous operation is completed. The begin method synchronously returns an object that implements the IAsyncResult interface. The caller can use the methods of this interface to determine the status of the asynchronous operation. The server typically maintains any state that is associated with an asynchronous operation in this waitable object.

The IAsyncResult interface specifies the properties that are listed in the following table.

IAsyncResult interface property

Description

AsyncState

AsyncState returns the object that was provided as

 

the last parameter, as part of the begin operation

 

method call.

AsyncWaitHandle

The AsyncWaitHandle property returns the

 

WaitHandle that is set after the server has

 

completed processing of the call.

CompletedSynchronously

The CompletedSynchronously property is set to

 

true if the begin operation call completes

 

synchronously.

IsCompleted

The IsCompleted property is set to true after the

 

server completes processing of the call.

Obtaining the results of the asynchronous operation

In the second part of an asynchronous call, the caller obtains the results of the operation in one of the four following ways:

!Callback Method

If the caller supplied the optional AsyncCallback delegate, the callback method referred to by this delegate will be called when the operation completes.

!Polling

The caller can poll the returned IAsyncResult interface’s IsCompleted property to determine if the call has completed.

!End Operation Method

The caller can attempt to complete the operation by calling the end operation method, thereby blocking until the operation completes.

!WaitHandle, End Operation Method

The caller can wait on the IAsyncResult interface’s WaitHandle property. One difference between this and the previous option is that the client can use time outs to wake up periodically. Another difference is that the caller can choose to wait for multiple events to occur by calling the WaitAll method in the Thread.WaitHandle class and specifying an array of events, see the topic, Using the WaitHandle class to wait for events in this module.

78

Module 14 (Optional): Threading and Asynchronous Programming

Note Cancel is not provided on IAsyncResult, because in many implementations, there is no guarantee that an asynchronous operation will be canceled.

Exceptions

If the begin operation method throws an exception, the caller can assume that an asynchronous operation was not started and that the callback delegate will not be called.

After an asynchronous operation starts, the client is notified of any exceptions that are raised by the server when the client calls the end operation method.

Module 14 (Optional): Threading and Asynchronous Programming

79

 

 

 

Asynchronous File Stream Read Example

Topic Objective

To show the first part of the Asynchronous File Stream Read example by explaining how to do an asynchronous read using a callback.

Lead-in

Let’s first look at how to do an asynchronous read by using a callback.

! Asynchronous read with callback

# Create callback method delegate

AsyncCallback myCallback = new

AsyncCallback myCallback = new

AsyncCallback(this.OnReadDone);

AsyncCallback(this.OnReadDone);

# Begin the operation

IAsyncResult ar = aStream.BeginRead(buffer,0, IAsyncResult ar = aStream.BeginRead(buffer,0,

buffer.Length, myCallback,(object)myState); buffer.Length, myCallback,(object)myState);

# In the callback method, complete the operations

int byteCount = aStream.EndRead(ar); //data in buffer int byteCount = aStream.EndRead(ar); //data in buffer

*****************************ILLEGAL FOR NON-TRAINER USE******************************

The examples in this topic show how to implement a client that uses the System.IO.Stream class’s methods to read a sequence of bytes from a file. The System.IO.Stream class’s synchronous read method is named Read and the asynchronous methods are named BeginRead and EndRead.

For the complete running code of these examples, see <install folder>\

Democode\Mod14\Demo14.6.

The following code uses a byte array named buffer to store the bytes returned from the read operation:

byte[] buffer = new byte [512]; string filename = "test.txt"

Stream aStream = File.OpenRead(filename);

The following code uses a synchronized call to read data from the file:

int byteCount = aStream.Read(buffer, 0, buffer.Length); aStream.Close();

Details of the asynchronous read operation

The asynchronous operation consists of two logical parts: the part that takes input from the client and calls the asynchronous operation, and the part that supplies results of the asynchronous operation to the client.

80

Module 14 (Optional): Threading and Asynchronous Programming

Asynchronous Read With Callback

In this example the callback method is an instance method named OnReadDone, which returns void and takes a single parameter of type IAsyncResult. The System namespace defines a delegate class AsyncCallback that matches the signature for the instance method so that there is no need to declare a new delegate type.

You create the callback delegate object as follows:

AsyncCallback myCallback = new AsyncCallback(this.OnReadDone);

If the caller may issue multiple asynchronous calls, the caller must be able to correlate each of the results to the original call. You can use the state parameter of the method that makes the asynchronous call to store this information.

In this example, you store the name of the file being read in an instance of

MyState:

class MyState

{

public string filename;

public MyState(string filename) { this.filename = filename;

}

}

// ...

MyState myState = new MyState(filename);

You can now make the asynchronous call as follows:

IAsyncResult ar = aStream.BeginRead(

buffer, 0, buffer.Length, myCallback, (object)myState); // continue to execute

The BeginRead method returns and the thread can continue to execute while the read operation proceeds. When the read operation completes, the OnReadDone method is called, possibly on a separate thread. This method performs the second part of the asynchronous operation, obtaining the results of the operation as follows:

int byteCount = aStream.EndRead(ar); // data now in buffer Console.WriteLine("Filename read: {0},

((MyState)(ar.AsyncState)).filename); aStream.Close();

The next topic, Asynchronous File Stream Read Example (Continued), completes the example, by showing how to do an asynchronous read with polling.

Module 14 (Optional): Threading and Asynchronous Programming

81

 

 

 

Asynchronous File Stream Read Example (continued)

Topic Objective

To continue the Asynchronous File Stream Read example by explaining how to do an asynchronous read with polling.

Lead-in

Now let’s see how to do an asynchronous read with polling.

!Asynchonous read with polling

#Begin the operation

IAsyncResult ar = aStream.BeginRead(buffer,0, IAsyncResult ar = aStream.BeginRead(buffer,0,

buffer.Length, null,(object)myState); buffer.Length, null,(object)myState);

# Poll and complete

while (!ar.IsCompleted){ // do whatever while (!ar.IsCompleted){ // do whatever

}}

int byteCount = aStream.EndRead(ar); // data in buffer int byteCount = aStream.EndRead(ar); // data in buffer

*****************************ILLEGAL FOR NON-TRAINER USE******************************

The preceding topic showed how to complete an asynchronous read operation by using a callback delegate. In this topic, you will see how to obtain results of the asynchronous read with polling.

Asynchronous Read with Polling

To handle the second part of the asynchronous operation by polling for completion rather than using a callback method, you make the initial asynchronous call by supplying a null value for the callback method.

IAsyncResult ar = aStream.BeginRead(

buffer, 0, buffer.Length,null, (object)myState);

The BeginRead method returns and the thread can continue to execute while the read operation proceeds. In this case, the thread periodically polls the IsCompleted property of the IAsyncResult to determine when the read operation is complete.

while (!ar.IsCompleted)

{

// do whatever

}

int byteCount = aStream.EndRead(ar); // data now in buffer Console.WriteLine("Filename read: {0},

((MyState)(ar.AsyncState)).filename); aStream.Close();

82

Module 14 (Optional): Threading and Asynchronous Programming

Demonstration: Asynchronous File Stream Read

Topic Objective

To demonstrate how to use synchronous and asynchronous read methods on a file stream.

Lead-in

In this demonstration, you will see how to use synchronous and asynchronous read methods on a file stream.

*****************************ILLEGAL FOR NON-TRAINER USE******************************

This demonstration shows how to use synchronous and asynchronous read methods on a file stream. For the asynchronous case, the four different ways to complete the operation are shown: callback, poll, end method call, and wait with timeout.

Notice that in the asynchronous case that uses a callback method, the callback method may be executed on a different thread than the main code.

The code for this demonstration is located in <install folder>\Democode\

Mod14\Demo14.6.

Соседние файлы в папке c#