在WP7下载内容时,用户界面冻结
本文关键字:用户界面 冻结 WP7 下载 | 更新日期: 2023-09-27 18:05:22
我是WP7编码的新手。我正在寻找示例代码或指导以下任务:
我在远程服务器上有3个html页面,我想下载每个页面的内容,并将其发布到3个不同的全景页面(显示为文本块)。
我写了3套web客户端来加载html页面;它可以显示在它应该在的地方。我面临的问题是,当/在下载期间,UI线程是"冻结"和无响应。
谁能指导我/告诉我的样本代码,我可以把线程后台,一旦它完成,并显示在UI?
这是我用来下载HTML页面的代码
private async void GetNewsIndex(string theN)
{
string newsURI = newsURL + theN;
string fileName = theN + "-temp.html";
string folderName = "news";
prgBar01.Visibility = System.Windows.Visibility.Visible;
try
{
Task<string> contentDataDownloaded = new WebClient().DownloadStringTaskAsync(new Uri(newsURI));
string response = await contentDataDownloaded;
WriteTempFile(theN, response.ToString());
string contentData = ProcessDataToXMLNews(fileName, folderName);
WritenewsIndexXMLFile(newsIndexURI, folderName, contentData);
DisplayNewsIndex();
}
catch
{
//
}
}
我按照Sinh Pham的建议修改了上面的代码,它像预期的那样完美地工作。但是,因为我需要运行3个瞬间它下载页面从不同的来源在同一时间;代码中断。任何想法?
你确定UI在下载时冻结,而不是在处理数据时冻结吗?从你的代码中,你似乎只做了
WriteTempFile(theN, response.ToString());
string contentData = ProcessDataToXMLNews(fileName, folderName);
WritenewsIndexXMLFile(newsIndexURI, folderName, contentData);
DisplayNewsIndex();
UI线程上的。尝试将它们封装在BackgroundWorker中。
编辑:像这样:
Edit2:因为你的DisplayNewsIndex()函数会引起UI的变化,所以它必须在UI线程上执行。
var bw = new BackgroundWorker();
bw.DoWork += delegate {
WriteTempFile(theN, response.ToString());
string contentData = ProcessDataToXMLNews(fileName, folderName);
WritenewsIndexXMLFile(newsIndexURI, folderName, contentData);
Deployment.Current.Dispatcher.BeginInvoke(() => {
DisplayNewsIndex();
});
};
bw.RunWorkerAsync();
你可以考虑使用HttpWebRequest。这在后台线程上异步工作,与WebClient
内部使用的相同。WebClient只是抽象了较低级的工作,但是,正如您所看到的,它的缺点是在UI线程上返回。这里有一个如何使用HttpWebRequest的例子
下载是完全异步的。但是你的问题是UI线程上的数据处理。您应该考虑在另一个线程上执行此操作。
无论你在哪里开始的。webClient()或它是异步或不(我怀疑你有其他的选择,而不是异步在windows phone webClient)"它完全运行在UI线程上"。
这就是你的UI被冻结的原因。这实际上是一个错误,所以其他人也建议你应该考虑使用HttpWebRequest
代替。我要在下面添加一个链接到我的博客文章,其中包含一个名为WebDownloader
的Helper类,它减少了所有的麻烦,使您的生活更轻松:
你唯一需要做的就是:
var downloader = new WebDownloader{ Url = "something" };
downloader.OnCompleted += (a, b) => { /*downloader.Result is ready!*/ };
downloader.OnFailed += (a, b) => { /*download failed!*/ };
downloader.Download();
你也可以选择取消你的下载任务,通过调用它,像这样:
downloader.Cancel();
这是因为您可能正在主线程(UI线程)上下载内容。当您这样做时,它将占用该线程的所有资源,使处理器没有时间更新屏幕。将下载移到后台,它将(如果这是问题)得到解决!