Reset
Sets the state of the specified event to nonsignaled.Set
Sets the state of the specified event to signaled.
Sets the state of the specified event to nonsignaled.Set
Sets the state of the specified event to signaled.
下面的 C# 示例程序说明如何通过 WebRequest 类使用异步调用。该示例是一个控制台程序,它从命令行获得 URI,请求此 URI 处的资源,然后在从 Internet 接收数据的过程中在控制台上打印数据。该程序定义了两个供自己使用的类:一个是 RequestState 类,它在异步调用间传递数据;另一个是 ClientGetAsync 类,它实现对 Internet 资源的异步请求。 RequestState 类在服务于请求的异步方法调用间保留请求的状态。在 RequestState 类中,有包含当前资源请求和收到的响应流的 WebRequest 和 Stream 实例、包含当前从 Internet 资源接收到的数据的缓冲区和包含整个响应的 StringBuilder 实例。当 AsyncCallback 方法向 WebRequest.BeginGetResponse 注册时,RequestState 实例 (ar) 作为 state 参数传递。ClientGetAsync 类实现对 Internet 资源的异步请求,并将结果响应写到控制台。此类包含以下列表中描述的方法和属性。 allDone 属性包含 ManualResetEvent 类的一个实例,该实例发出信号表示请求已完成。
Main() 方法读取命令行并开始对指定 Internet 资源的请求。此方法创建 WebRequest 实例 wreq 和 RequestState 实例 ar,调用 BeginGetResponse 开始处理请求,然后调用 allDone.WaitOne() 方法,以使应用程序在回调完成后才退出。读取来自 Internet 资源的响应后,Main() 将响应写到控制台,然后应用程序结束。
showusage() 方法将示例命令行写到控制台。如果命令行中没有提供 URI,Main() 将调用此方法。
RespCallBack() 方法为 Internet 请求实现异步回调方法。此方法创建包含来自 Internet 资源的响应的 WebResponse 实例,获取响应流,然后开始从该流中异步读取数据。
ReadCallBack() 方法实现读取响应流的异步回调方法。它将从 Internet 资源接收的数据传输到 RequestState 实例的 ResponseData 属性中,然后对响应流启动另一个异步读取,直到不再有数据返回为止。读取完所有数据后,ReadCallBack() 关闭响应流,并调用 allDone.Set() 方法以指示 ResponseData 中的响应是完整的。
注意 关闭所有网络流至关重要。如果没有将所有的请求和响应流都关闭,应用程序将用完服务器连接,而无法处理其他请求。
using System.Net;
using System.Threading;
using System.Text;
using System.IO;// The RequestState class passes data across async calls.
public class RequestState
{
const int BufferSize = 1024;
public StringBuilder RequestData;
public byte[] BufferRead;
public WebRequest Request;
public Stream ResponseStream;
// Create Decoder for appropriate enconding type.
public Decoder StreamDecode = Encoding.UTF8.GetDecoder();
public RequestState()
{
BufferRead = new byte[BufferSize];
RequestData = new StringBuilder(String.Empty);
Request = null;
ResponseStream = null;
}
}// ClientGetAsync issues the async request.
class ClientGetAsync
{
public static ManualResetEvent allDone = new ManualResetEvent(false);
const int BUFFER_SIZE = 1024; public static void Main(string[] args)
{
if (args.Length < 1)
{
showusage();
return;
} // Get the URI from the command line.
Uri httpSite = new Uri(args[0]); // Create the request object.
WebRequest wreq = WebRequest.Create(httpSite);
// Create the state object.
RequestState rs = new RequestState(); // Put the request into the state object so it can be passed around.
rs.Request = wreq; // Issue the async request.
IAsyncResult r = (IAsyncResult) wreq.BeginGetResponse(
new AsyncCallback(RespCallback), rs); // Wait until the ManualResetEvent is set so that the application
// does not exit until after the callback is called.
allDone.WaitOne(); Console.WriteLine(rs.RequestData.ToString());
} public static void showusage() {
Console.WriteLine("Attempts to GET a URL");
Console.WriteLine("\r\nUsage:");
Console.WriteLine(" ClientGetAsync URL");
Console.WriteLine(" Example:");
Console.WriteLine(" ClientGetAsync http://www.contoso.com/");
} private static void RespCallback(IAsyncResult ar)
{
// Get the RequestState object from the async result.
RequestState rs = (RequestState) ar.AsyncState; // Get the WebRequest from RequestState.
WebRequest req = rs.Request; // Call EndGetResponse, which produces the WebResponse object
// that came from the request issued above.
WebResponse resp = req.EndGetResponse(ar); // Start reading data from the response stream.
Stream ResponseStream = resp.GetResponseStream(); // Store the response stream in RequestState to read
// the stream asynchronously.
rs.ResponseStream = ResponseStream; // Pass rs.BufferRead to BeginRead. Read data into rs.BufferRead
IAsyncResult iarRead = ResponseStream.BeginRead(rs.BufferRead, 0,
BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
}
private static void ReadCallBack(IAsyncResult asyncResult)
{
// Get the RequestState object from AsyncResult.
RequestState rs = (RequestState)asyncResult.AsyncState; // Retrieve the ResponseStream that was set in RespCallback.
Stream responseStream = rs.ResponseStream; // Read rs.BufferRead to verify that it contains data.
int read = responseStream.EndRead( asyncResult );
if (read > 0)
{
// Prepare a Char array buffer for converting to Unicode.
Char[] charBuffer = new Char[BUFFER_SIZE];
// Convert byte stream to Char array and then to String.
// len contains the number of characters converted to Unicode.
int len =
rs.StreamDecode.GetChars(rs.BufferRead, 0, BUFFER_SIZE, charBuffer, 0);
String str = new String(charBuffer, 0, len); // Append the recently read data to the RequestData stringbuilder
// object contained in RequestState.
rs.RequestData.Append(
Encoding.ASCII.GetString(rs.BufferRead, 0, read)); // Continue reading data until
// responseStream.EndRead returns –1.
IAsyncResult ar = responseStream.BeginRead(
rs.BufferRead, 0, BUFFER_SIZE,
new AsyncCallback(ReadCallBack), rs);
}
else
{
if(rs.RequestData.Length>0)
{
// Display data to the console.
string strContent;
strContent = rs.RequestData.ToString();
}
// Close down the response stream.
responseStream.Close();
// Set the ManualResetEvent so the main thread can exit.
allDone.Set();
}
return;
}
}