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秒)(我可以使用调试器观看)。
为什么?这是我的错误还是职能部门的标准行为?
你可以试试,我相信那更好
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 中的全部内容