获取异步HttpWebRequest的响应

gdp*_*gdp 18 c# asynchronous httpwebrequest httpwebresponse

我想知道是否有一个简单的方法来获得异步httpwebrequest的响应.

我已经在这里看到了这个问题但是我试图做的就是将字符串形式的响应(通常是json或xml)返回到另一个方法,然后我可以解析它/相应地处理它.

下面是一些代码:

我在这里有这两个静态方法我认为是线程安全的,因为所有的参数都被传入并且方法没有共享的局部变量?

public static void MakeAsyncRequest(string url, string contentType)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.ContentType = contentType;
    request.Method = WebRequestMethods.Http.Get;
    request.Timeout = 20000;
    request.Proxy = null;

    request.BeginGetResponse(new AsyncCallback(ReadCallback), request);
}

private static void ReadCallback(IAsyncResult asyncResult)
{
    HttpWebRequest request = (HttpWebRequest)asyncResult.AsyncState;
    try
    {
        using (HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asyncResult))
        {
            Stream responseStream = response.GetResponseStream();
            using (StreamReader sr = new StreamReader(responseStream))
            {
                //Need to return this response 
                string strContent = sr.ReadToEnd();
            }
       }
       manualResetEvent.Set();
    }
    catch (Exception ex)
    {
        throw ex;
   }
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*ing 41

假设问题是您很难获得返回的内容,最简单的路径可能是使用async/await,如果您可以使用它.如果您使用的是.NET 4.5,那么更好的方法是切换到HttpClient,因为它本身就是"异步".

使用.NET 4和C#4,您仍然可以使用Task来包装这些并使其更容易访问最终结果.例如,一个选项如下.请注意,在内容字符串可用之前,它会使Main方法阻塞,但在"真实"场景中,您可能会将任务传递给其他内容,或者将另一个ContinueWith串起来或其他任何内容.

void Main()
{
    var task = MakeAsyncRequest("http://www.google.com", "text/html");
    Console.WriteLine ("Got response of {0}", task.Result);
}

// Define other methods and classes here
public static Task<string> MakeAsyncRequest(string url, string contentType)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.ContentType = contentType;
    request.Method = WebRequestMethods.Http.Get;
    request.Timeout = 20000;
    request.Proxy = null;

    Task<WebResponse> task = Task.Factory.FromAsync(
        request.BeginGetResponse,
        asyncResult => request.EndGetResponse(asyncResult),
        (object)null);

    return task.ContinueWith(t => ReadStreamFromResponse(t.Result));
}

private static string ReadStreamFromResponse(WebResponse response)
{
    using (Stream responseStream = response.GetResponseStream())
    using (StreamReader sr = new StreamReader(responseStream))
    {
        //Need to return this response 
        string strContent = sr.ReadToEnd();
        return strContent;
    }
}
Run Code Online (Sandbox Code Playgroud)


mir*_*aki 7

"如果您使用的是.NET 4.5,那么更好的方法就是切换到HttpClient,因为它本身就是'异步'." - 詹姆斯曼宁绝对正确的答案.大约2年前就提出了这个问题.现在我们有.NET framework 4.5,它提供了强大的异步方法.使用HttpClient.请考虑以下代码:

 async Task<string> HttpGetAsync(string URI)
    {
        try
        {
            HttpClient hc = new HttpClient();
            Task<Stream> result = hc.GetStreamAsync(URI);

            Stream vs = await result;
            StreamReader am = new StreamReader(vs);

            return await am.ReadToEndAsync();
        }
        catch (WebException ex)
        {
            switch (ex.Status)
            {
                case WebExceptionStatus.NameResolutionFailure:
                    MessageBox.Show("domain_not_found", "ERROR",
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                break;
                    //Catch other exceptions here
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

要使用HttpGetAsync(),请创建一个"异步"的新方法.async是必需的,因为我们需要在GetWebPage()方法中使用"await":

async void GetWebPage(string URI)
        {
            string html = await HttpGetAsync(URI);
            //Do other operations with html code
        }
Run Code Online (Sandbox Code Playgroud)

现在,如果您想异步获取网页html源代码,只需调用GetWebPage("web-address ...")即可.甚至Stream读取也是异步的.

注意:要使用HttpClient,.NET Framework 4.5是必需的.您还需要System.Net.Http在项目中添加引用,并添加" using System.Net.Http"以便于访问.

有关此方法的工作原理,请访问:http://msdn.microsoft.com/en-us/library/hh191443(v = vs1010).aspx

使用Async:4.5中的异步:值得期待