using (var stream = new StreamWriter(request.GetRequestStream(), Encoding))
stream.Write(body.ToString());
我需要将它变成异步的。据我所知,这意味着我需要将对 request.GetRequestStream()
的调用更改为 asynchronous.BeginGetRequestStream()
。我看过了这个例子,但无法弄清如何将其应用到这种情况。有人能帮忙吗?
using (var stream = new StreamWriter(request.GetRequestStream(), Encoding))
stream.Write(body.ToString());
我需要将它变成异步的。据我所知,这意味着我需要将对 request.GetRequestStream()
的调用更改为 asynchronous.BeginGetRequestStream()
。我看过了这个例子,但无法弄清如何将其应用到这种情况。有人能帮忙吗?
文档中有一个很好的例子 (http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetrequeststream(v=vs.100).aspx):
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Threading;
class HttpWebRequestBeginGetRequest
{
private static ManualResetEvent allDone = new ManualResetEvent(false);
public static void Main(string[] args)
{
// Create a new HttpWebRequest object.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.contoso.com/example.aspx");
request.ContentType = "application/x-www-form-urlencoded";
// Set the Method property to 'POST' to post data to the URI.
request.Method = "POST";
// start the asynchronous operation
request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), request);
// Keep the main thread from continuing while the asynchronous
// operation completes. A real world application
// could do something useful such as updating its user interface.
allDone.WaitOne();
}
private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
Stream postStream = request.EndGetRequestStream(asynchronousResult);
Console.WriteLine("Please enter the input data to be posted:");
string postData = Console.ReadLine();
// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Write to the request stream.
postStream.Write(byteArray, 0, postData.Length);
postStream.Close();
// Start the asynchronous operation to get the response
request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
}
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
// End the operation
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string responseString = streamRead.ReadToEnd();
Console.WriteLine(responseString);
// Close the stream object
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse
response.Close();
allDone.Set();
}
你可以通过这段代码理解。
该程序定义了两个类供自己使用,RequestState类用于在异步调用之间传递数据,ClientGetAsync类实现对Internet资源的异步请求。
RequestState类跨异步方法调用保留请求状态。它包含WebRequest和Stream实例,其中包含当前请求到资源的请求和响应中接收到的流,一个包含当前从Internet资源接收到的数据的缓冲区以及一个包含完整响应的StringBuilder。当使用WebRequest.BeginGetResponse注册AsyncCallback方法时,RequestState作为状态参数传递。
ClientGetAsync类实现对Internet资源的异步请求,并将结果响应写入控制台。它包含以下列表中描述的方法和属性。
allDone属性包含ManualResetEvent类的实例,该实例表示请求完成。
Main()方法读取命令行并开始请求指定的Internet资源。它创建WebRequest wreq和RequestState rs,调用BeginGetResponse开始处理请求,然后调用allDone.WaitOne()方法,以便应用程序在回调完成之前不会退出。从Internet资源读取响应后,Main()将其写入控制台,应用程序结束。
showusage() 方法在控制台上编写一个示例命令行。当命令行中未提供 URI 时,Main()将调用该方法。
RespCallBack() 方法实现了 Internet 请求的异步回调方法。它创建包含来自 Internet 资源响应的 WebResponse 实例,获取响应流,然后开始异步地读取流中的数据。
ReadCallBack() 方法实现了读取响应流的异步回调方法。它将从 Internet 资源接收到的数据传输到 RequestState 实例的 ResponseData 属性中,然后启动另一个异步读取响应流,直到没有返回更多数据为止。一旦所有数据都已读取,ReadCallBack() 将关闭响应流并调用 allDone.Set() 方法以指示整个响应存在于 ResponseData 中。
using System;
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, read, 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;
}
}
using (var stream = ...){await stream.WriteAsync(body.ToString());}
即可。 - John SaundersStream
而不是StreamWriter
。 - John Saunders