如何在for循环中使用dispatcher.BeginInvoke(httpwebrequest)。在调用另一个dispatcher.BeginInvoke之前,每个dispatcher.BeginInvoke都已完成。因为httpwerequest返回的对象是错误的位置。
答案 0 :(得分:3)
不,BeginInvoke
是异步的 - 您基本上是将委托添加到要在UI线程上执行的项目队列。
如果您需要等到代理执行完之后再继续在后台线程中工作,那么您需要自己做一些工作,因为Silverlight不支持同步Dispatcher.Invoke
方法,或者DispatcherOperation.Wait()
方法。 Silverlight试图避免这样的同步方法 - 如果您可以重新设计代码以便不需要等待,那将是更好的。
答案 1 :(得分:0)
能够轻松地将同步操作序列转换为异步代码一直是我写博客的一个主题。如果你想采用我的方法,你需要添加以下(相对较小的)代码块:
以下是一些示例代码,其中包含您在问题中描述的内容: -
IEnumerable<AsyncOperation> LoadSomeStuff(IList<string> urls)
{
for (string url in urls)
{
yield return AsyncOperationService.SwitchToBackgroundThread();
WebRequest req = WebRequest.Create(url);
WebResponse resp = null;
yield return req.GetResponseAsyncOp(r => resp = r);
using (resp)
{
// Do stuff with the Web Response such as construct model class instances from a stream.
}
// When ready to actually start touching the UI
yield return AsyncOperationService.SwitchToUIThread();
// Do stuff to the UI
}
}
用法:
List<string> urls = new List<string> {"pinkElephants.xml", "whileElephants.xml"}
LoadSomeStuff(urls).Run(err =>
{
if (err == null)
{
// Cool, it all worked and I probably don't need to do anything
}
else
{
// Something bad happened, lets tell the user about it in the UI somehow.
}
});
请注意,这不是最有效的代码。然而,在许多情况下,大量传递HTTP响应的时间超过了其余代码耗尽的时间,因此低效率可能非常小,非常值得降低代码的复杂性。