HttpWebRequest.BeginGetResponse

本文关键字:BeginGetResponse HttpWebRequest | 更新日期: 2023-09-27 18:25:12

我需要向web资源发出异步请求,并使用此页面中的示例(完整示例的链接):

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秒)(我可以使用调试器观看)。

为什么?这是我的错误还是职能部门的标准行为?

HttpWebRequest.BeginGetResponse

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

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;
}

由于文本框值的chross线程,但这是wpf应用程序,我会重新标记它,顺便说一句,你可以使用类似的Web客户端

 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
        }
    } 

这是标准行为。

来自HttpWebRequest.BeginGetResponse方法的文档:

BeginGetResponse方法需要完成一些同步设置任务(例如,DNS解析、代理检测和TCP套接字连接),然后该方法才能变为异步。[…]在引发错误异常或方法成功之前,完成初始同步设置任务可能需要相当长的时间(根据网络设置,最多需要几分钟)。

为了避免等待安装,您可以使用HttpWebRequest.BeginGetRequestStream方法但要注意:

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

响应发生在一个单独的线程上。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,而是运行一些旋转消息循环,这在那里也有效。从根本上讲,这并不是最后一种情况下最新平台的"最佳答案"。但在合适的情况下,它可能更便携。如果这能帮助一个人避免设计错误,那么我花时间写这篇文章是值得的

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

相关文章:
  • 没有找到相关文章