HttpWebRequest.BeginGetResponse

时间:2012-02-21 07:32:13

标签: c# .net wpf asynchronous httpwebrequest

我需要向网络资源发出异步请求并使用此页面中的示例(link to full example):

HttpWebRequest myHttpWebRequest= (HttpWebRequest)WebRequest.Create("http://www.contoso.com");
RequestState myRequestState = new RequestState();  
myRequestState.request = myHttpWebRequest;
// Start the asynchronous request.
IAsyncResult result=
        (IAsyncResult) myHttpWebRequest.BeginGetResponse(new AsyncCallback(RespCallback),myRequestState);

但是当我测试应用程序时,执行冻结(在2-3秒内)在此代码的最后一行(我可以使用调试器观察它)。

为什么呢?这是我的错误还是函数的标准行为?

4 个答案:

答案 0 :(得分:6)

你可以尝试,我相信那更好郎

private void StartWebRequest(string url)
{
   HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
   request.BeginGetResponse(new AsyncCallback(FinishWebRequest), request);
}

private void FinishWebRequest(IAsyncResult result)
{
   HttpWebResponse response = (result.AsyncState as HttpWebRequest).EndGetResponse(result) as HttpWebResponse;
}

由于textbox'值的冗长线程,但这是wpf应用程序我将重新点这个,顺便说一句你可以使用webclient

 private void tbWord_TextChanged(object sender, TextChangedEventArgs e)
    {
        WebClient wc = new WebClient();
        wc.DownloadStringCompleted += HttpsCompleted;
        wc.DownloadStringAsync(new Uri("http://en.wikipedia.org/w/api.php?action=opensearch&search=" + tbWord.Text)); 
    }
    private void HttpsCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        if (e.Error == null)
        {

             //do what ever 
             //with using e.Result
        }
    } 

答案 1 :(得分:2)

响应发生在单独的线程上。 Winforms不是多线程安全的,因此您将不得不在与表单相同的线程上调度该调用。

您可以使用窗口的内部消息循环执行此操作。幸运的是,.NET提供了一种方法。您可以使用控件的Invoke或BeginInvoke方法来执行此操作。前者阻塞当前线程,直到UI线程完成调用的方法。后者以异步方式执行此操作。除非有清理工作,否则你可以使用后者来“发射并忘记”

为了使其以任何一种方式工作,您需要创建一个由BeginInvoke调用的方法,并且您需要一个委托来指向该方法。

有关详细信息,请参阅MSDN中的Control.Invoke和Control.BeginInvoke。

此链接有一个示例:https://msdn.microsoft.com/en-us/library/zyzhdc6b(v=vs.110).aspx

更新:因为我正在浏览我的个人资料,因为我忘记了我在这里有一个帐户 - 我注意到这一点,我应该补充:任何超过3.5或当他们显着改变异步线程模型时,这是我的驾驶室。我很专业,虽然我仍然喜欢这种技艺,但我并不追求每一个进步。我可以告诉你的是,这个应该在所有版本的.NET中都可以工作,但它可能不是性能4.0及其他版本的绝对顶峰,也可能不是Mono / Winforms仿真的绝对顶峰,如果它仍然存在的话。从好的方面来说,任何打击通常都不会在服务器应用程序之外变坏,甚至在线程池正在执行其工作时也是如此。所以在大多数情况下不要把优化工作集中在这里,并且更有可能在你看到运行C#移动包这样的“剥离”平台上工作,尽管我必须确保并且大多数都不运行winforms但是一些旋转消息循环,这也适用于那里。基本上,在最后一种情况下,它不是最新平台的“最佳答案”。但在正确的情况下它可能更便携。如果这有助于一个人避免设计错误,那么我花时间写这篇文章是值得的。 =)

答案 2 :(得分:1)

您可以使用BackgroundWorker添加DoWork中的全部内容

答案 3 :(得分:1)

这是标准行为。

来自documentation on HttpWebRequest.BeginGetResponse Method

  

在此方法变为异步之前,BeginGetResponse方法需要完成一些同步设置任务(例如,DNS解析,代理检测和TCP套接字连接)。 [...]   在抛出错误异常或方法成功之前,可能需要相当长的时间(最多几分钟,具体取决于网络设置)才能完成初始同步设置任务。

为避免等待设置,您可以使用 HttpWebRequest.BeginGetRequestStream Method 但请注意:

  

您的应用程序不能为特定请求混合使用同步和异步方法。如果调用BeginGetRequestStream方法,则必须使用BeginGetResponse方法来检索响应。