我有一些文件需要在app启动时下载(首次运行)。 我在Windows 8中使用Background Downloader。 这就是我使用它的方式:
BackgroundDownloader downloader = new BackgroundDownloader();
List<DownloadOperation> operations = new List<DownloadOperation>();
foreach (FileInfo info in infoFiles)
{
Windows.Storage.ApplicationData.Current.LocalFolder;
foreach (string folder in info.Folders)
{
currentFolder = await currentFolder.CreateFolderAsync(folder, CreationCollisionOption.OpenIfExists);
}
//folder hierarchy created, save the file
StorageFile file = await currentFolder.CreateFileAsync(info.FileName, CreationCollisionOption.ReplaceExisting);
DownloadOperation op = downloader.CreateDownload(new Uri(info.Url), file);
activeDownloads.Add(op);
operations.Add(op);
}
foreach (DownloadOperation download in operations)
{
//start downloads
await HandleDownloadAsync(download, true);
}
当我尝试使用BackgroundDownloader.GetCurrentDownloadsAsync();
时,我只发现了一个后台下载。所以我删除了上面的await运算符,让它们以异步方式启动。
但是我需要知道所有文件何时完成,所以我可以设置进度条。
我需要一种方法来下载多个文件,在BackgroundDownloader.GetCurrentDownloadsAsync();
中发现所有文件,并知道所有下载完成的时间。
private async Task HandleDownloadAsync(DownloadOperation download, bool start)
{
try
{
Debug.WriteLine("Running: " + download.Guid, NotifyType.StatusMessage);
// Store the download so we can pause/resume.
activeDownloads.Add(download);
Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
if (start)
{
// Start the download and attach a progress handler.
await download.StartAsync().AsTask(cts.Token, progressCallback);
}
else
{
// The download was already running when the application started, re-attach the progress handler.
await download.AttachAsync().AsTask(cts.Token, progressCallback);
}
ResponseInformation response = download.GetResponseInformation();
Debug.WriteLine(String.Format("Completed: {0}, Status Code: {1}", download.Guid, response.StatusCode),
NotifyType.StatusMessage);
}
catch (TaskCanceledException)
{
Debug.WriteLine("Canceled: " + download.Guid, NotifyType.StatusMessage);
}
catch (Exception ex)
{
if (!IsExceptionHandled("Execution error", ex, download))
{
throw;
}
}
finally
{
activeDownloads.Remove(download);
}
}
答案 0 :(得分:3)
如果您特别需要在每次应用启动时重新下载该文件,则不应使用BackgroundDownloader - 它适用于需要下载的情况,即使您的应用程序被暂停然后重新启动也会继续发生。如果您在下次启动应用时再次重新下载文件,那么只需在应用消失后继续下载,就会浪费电池。
对于Windows应用商店应用中的非后台下载,您有几个选项。关于如何使用它,最直接的是Windows.Web.Http.HttpClient - here's a good primer。但是,它仅适用于Windows 8.1应用程序,而不适用于Windows 8.0。如果您需要Windows 8.0兼容性,那么不同但名称相似的System.Net.Http.HttpClient可能就是这样。哈里森已经提供了the relevant Quickstart documentation的链接。
如果您确实需要后台下载功能,请修改您的问题以更准确地反映您的方案。当然可以使用BackgroundDownloader同时启动多个后台下载并将进度和完成处理程序附加到每个后台,但这听起来不是问题中方案的最佳解决方案。
现在您已经明确了用法,问题就更清楚了。您的HandleDownloadAsync
方法正在附加您想要下载的进度处理程序,但随后它正在等待下载完成。当你写
foreach (DownloadOperation download in operations)
{
//start downloads
await HandleDownloadAsync(download, true);
}
因此,在您开始下一次下载之前,您依次等待每次下载的完成。
这里的解决方案是不等待HandleDownloadAsync
来电的结果,直到之后你已经执行了所有的通话 - 这将启动每个立即下载并附加适当的进度处理程序,而不等待它们中的任何一个完成。修订版可能如下所示:
BackgroundDownloader downloader = new BackgroundDownloader();
List<Task> downloadCompletionTasks = new List<Task>();
foreach (FileInfo info in infoFiles)
{
StorageFile file = /* ... */;
DownloadOperation op = downloader.CreateDownload(new Uri(info.Url), file);
// Consider moving this line into HandleDownloadAsync so you won't have to repeat
// it in the code that's handling the GetCurrentDownloadsAsync logic.
activeDownloads.Add(op);
// Starting the download, but not awaiting its completion yet
Task downloadCompletionTask = HandleDownloadAsync(op, true);
downloadCompletionTasks.Add(downloadCompletionTask);
}
// Now that we've got all the downloads started concurrently, we can wait until all of them complete
await Task.WhenAll(downloadCompletionTasks);