UWP中BackgroundTransfer调用StartAsync不等待下载完成的实现方案
实现结论
完全可以实现启动下载后无需等待完成、调度成功即返回的需求,且可以保证后续能通过BackgroundDownloader.GetCurrentDownloadsAsync()获取到对应任务。
具体实现方案
- 不要直接丢弃
StartAsync()返回的异步任务,你只需要等待任务被系统后台下载服务成功接收、进入调度队列即可返回,无需等待整个下载流程执行完毕。 - 核心逻辑是通过
Task.WhenAny做非阻塞等待,仅确认下载任务的状态进入已调度范畴就终止等待,不需要等待下载完成回调。
代码示例
using Windows.Networking.BackgroundTransfer; using Windows.Storage; // 调度下载方法,调度成功即返回 public async Task<bool> RunDownload(Uri downloadUri, StorageFile saveFile) { var downloader = new BackgroundDownloader(); DownloadOperation downloadOp = downloader.CreateDownload(downloadUri, saveFile); // 启动下载任务,转为Task方便状态判断 var downloadStartTask = downloadOp.StartAsync().AsTask(); // 等待任务进入调度状态,最多等待1秒可自行调整超时时间 await Task.WhenAny(downloadStartTask, Task.Delay(1000)); // 验证任务是否已成功进入系统后台传输队列 if (downloadOp.Status is BackgroundTransferStatus.Running or BackgroundTransferStatus.Idle or BackgroundTransferStatus.PausedByApplication or BackgroundTransferStatus.PausedCostedNetwork) { // 调度成功,直接返回,无需等待下载完成 return true; } // 调度失败的异常处理,可自行添加日志记录逻辑 if (downloadStartTask.Exception != null) { // 处理启动失败异常 } return false; }
注意事项
- 无需强制订阅
OnProgress、OnCompleted这类事件,后台下载任务由系统服务独立托管,和你的调度进程生命周期无关,即使调度任务所在的后台执行逻辑退出,已入队的下载任务仍会正常执行。 - 用户唤起UI查看进度时,直接调用
BackgroundDownloader.GetCurrentDownloadsAsync()就能获取到所有当前的下载任务,调用AttachAsync()即可绑定进度、完成回调做UI更新。 - 不要直接无等待调用
StartAsync(),否则如果调度过程中出现权限不足、存储空间不足等启动异常,你无法及时感知到调度失败的情况。
内容的提问来源于stack exchange,提问作者Tomy
相关产品推荐
相关产品推荐

