我需要向web资源发出异步请求并使用此页面中的示例(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秒内)在此代码的最后一行(我可以使用调试器观察它)。
为什么?这是我的错误还是函数的标准行为?
你可以试试,我相信那更好
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'值的chross线程,但是这是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
}
}
响应发生在单独的线程上。 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中的所有内容
这是标准行为。
来自documentation on HttpWebRequest.BeginGetResponse Method:
在此方法变为异步之前,BeginGetResponse方法需要完成一些同步设置任务(例如,DNS解析,代理检测和TCP套接字连接)。 [...]可能需要相当长的时间(最多几分钟,具体取决于网络设置)才能在抛出错误异常或方法成功之前完成初始同步设置任务。
为避免等待设置,您可以使用HttpWebRequest.BeginGetRequestStream Method但请注意:
您的应用程序不能为特定请求混合使用同步和异步方法。如果调用BeginGetRequestStream方法,则必须使用BeginGetResponse方法来检索响应。