当前位置:首页 > 操作系统 > Windows

背水一战 Windows 10 (119) - 后台任务: 后台下载任务(任务分组,组完成后触发后台任务)

[源码下载]

背水一战 Windows 10 (119) - 后台任务: 后台下载任务(任务分组,组完成后触发后台任务)


作者:webabcd

介绍
背水一战 Windows 10 之 后台任务

  • 后台下载任务(任务分组,组完成后触发后台任务)


示例
演示后台下载任务的分组,以及组任务全部完成后如何触发后台任务
/BackgroundTaskLib/BackgroundTaskTransfer.cs

            <span>/*</span>
            <span>
 * 后台任务,用于演示指定的一组后台下载任务全部完成后如何触发此后台任务
 * 
 * BackgroundTransferCompletionGroup - 分组对象(用于实现“组任务全部完成后触发后台任务”)
 *     Enable() - 启用“组任务全部完成后触发后台任务”的功能
 *     IsEnabled - 是否启用了“组任务全部完成后触发后台任务”的功能(只读)
 *     Trigger - “组任务全部完成后触发后台任务”的触发器
 *     
 * BackgroundDownloader - 后台下载任务管理器
 *     BackgroundDownloader(BackgroundTransferCompletionGroup completionGroup) - 通过指定的 BackgroundTransferCompletionGroup 对象实例化 BackgroundDownloader 对象
 *     CompletionGroup - 获取关联的 BackgroundTransferCompletionGroup 对象
 *     
 * 
 * 注:需要在 Package.appxmanifest 添加“后台任务”声明,支持的任务类型选择“系统事件”,并指定 EntryPoint(后台任务的类全名),类似如下:
 * <Extension Category="windows.backgroundTasks" EntryPoint="BackgroundTaskLib.BackgroundTaskTransfer">
 *   <BackgroundTasks>
 *     <Task Type="systemEvent" />
 *   </BackgroundTasks>
 * </Extension>
 </span>
            <span>*/</span>
            <span>using</span>
            <span> System;
</span>
            <span>using</span>
            <span> System.Collections.Generic;
</span>
            <span>using</span>
            <span> System.Threading.Tasks;
</span>
            <span>using</span>
            <span> Windows.ApplicationModel.Background;
</span>
            <span>using</span>
            <span> Windows.Data.Xml.Dom;
</span>
            <span>using</span>
            <span> Windows.Networking.BackgroundTransfer;
</span>
            <span>using</span>
            <span> Windows.UI.Notifications;

</span>
            <span>namespace</span>
            <span> BackgroundTaskLib
{
    </span>
            <span>public</span>
            <span>sealed</span>
            <span>class</span>
            <span> BackgroundTaskTransfer : IBackgroundTask
    {
        </span>
            <span>//</span>
            <span> 所注册的后台任务的名称</span>
            <span>public</span>
            <span>static</span>
            <span>string</span> TaskName { <span>get</span>; <span>set</span>; } = <span>"</span><span>Transfer</span><span>"</span><span>;
        </span><span>//</span><span> 所注册的后台任务的 EntryPoint,即后台任务的类全名</span><span>public</span><span>static</span><span>string</span> TaskEntryPoint { <span>get</span>; <span>set</span>; } = <span>"</span><span>BackgroundTaskLib.BackgroundTaskTransfer</span><span>"</span><span>;

        </span><span>//</span><span> 实现 IBackgroundTask 接口,其只有一个方法,即 Run()</span><span>public</span><span>void</span><span> Run(IBackgroundTaskInstance taskInstance)
        {
            </span><span>//</span><span> 获取 BackgroundTransferCompletionGroupTriggerDetails 对象,如果不是 null 则说明是 BackgroundTransferCompletionGroup.Trigger 触发的</span>
            BackgroundTransferCompletionGroupTriggerDetails details = taskInstance.TriggerDetails <span>as</span><span> BackgroundTransferCompletionGroupTriggerDetails;
            </span><span>if</span> (details == <span>null</span><span>)
            {
                </span><span>return</span><span>;
            }

            </span><span>//</span><span> 获取下载任务列表</span>
            List<DownloadOperation> failedDownloads = <span>new</span> List<DownloadOperation><span>();
            </span><span>int</span> successTotal = <span>0</span><span>;
            </span><span>foreach</span> (DownloadOperation download <span>in</span><span> details.Downloads)
            {
                </span><span>if</span><span> (IsFailed(download))
                {
                    </span><span>//</span><span> 保存失败的下载任务列表,稍后会重试</span><span>                    failedDownloads.Add(download);
                }
                </span><span>else</span><span>
                {
                    successTotal</span>++<span>;
                }
            }

            </span><span>if</span> (failedDownloads.Count > <span>0</span><span>)
            {
                </span><span>//</span><span> 重新下载失败的任务</span><span>                RetryDownloads(failedDownloads);
            }

            </span><span>//</span><span> 此后台任务执行完毕,弹出指定的 toast 通知</span><span>            ShowToast(successTotal, failedDownloads.Count);
        }

        </span><span>//</span><span> 判断指定的下载任务是否失败了</span><span>private</span><span>bool</span><span> IsFailed(DownloadOperation download)
        {
            BackgroundTransferStatus status </span>=<span> download.Progress.Status;
            </span><span>if</span> (status == BackgroundTransferStatus.Error || status ==<span> BackgroundTransferStatus.Canceled)
            {
                </span><span>return</span><span>true</span><span>;
            }

            ResponseInformation response </span>=<span> download.GetResponseInformation();
            </span><span>if</span> (response.StatusCode != <span>200</span><span>)
            {
                </span><span>return</span><span>true</span><span>;
            }

            </span><span>return</span><span>false</span><span>;
        }

        </span><span>//</span><span> 重新下载指定的任务</span><span>private</span><span>void</span> RetryDownloads(IEnumerable<DownloadOperation><span> downloads)
        {
            </span><span>//</span><span> 注册指定的后台任务,并返回与此后台任务相关联的 BackgroundDownloader 对象</span>
            BackgroundDownloader downloader =<span> BackgroundTaskTransfer.RegisterBackgroundTaskAndReturnBackgrounDownloader();

            </span><span>foreach</span> (DownloadOperation download <span>in</span><span> downloads)
            {
                </span><span>//</span><span> 创建并启动后台任务</span>
                DownloadOperation downloadNew =<span> downloader.CreateDownload(download.RequestedUri, download.ResultFile);
                Task</span><DownloadOperation> startTask =<span> downloadNew.StartAsync().AsTask();
            }

            </span><span>//</span><span> 启用“组任务全部完成后触发后台任务”的功能</span><span>            downloader.CompletionGroup.Enable();
        }

        </span><span>//</span><span> 注册指定的后台任务,并返回与此后台任务相关联的 BackgroundDownloader 对象
        </span><span>//</span><span> 后台任务的注册一般是在前台代码中写的,但是由于本例还有一个后台任务执行完成后重新下载失败任务的功能,所以这部分代码写在后台代码中就很合理了</span><span>public</span><span>static</span><span> BackgroundDownloader RegisterBackgroundTaskAndReturnBackgrounDownloader()
        {
            </span><span>//</span><span> 根据指定 BackgroundTransferCompletionGroup 对象创建一个 BackgroundDownloader 对象</span>
            BackgroundTransferCompletionGroup completionGroup = <span>new</span><span> BackgroundTransferCompletionGroup();
            BackgroundDownloader downloader </span>= <span>new</span><span> BackgroundDownloader(completionGroup);

            </span><span>//</span><span> 注册一个后台任务,并指定触发器为 BackgroundTransferCompletionGroup.Trigger</span>
            BackgroundTaskBuilder builder = <span>new</span><span> BackgroundTaskBuilder();
            builder.Name </span>=<span> BackgroundTaskTransfer.TaskName;
            builder.TaskEntryPoint </span>=<span> BackgroundTaskTransfer.TaskEntryPoint;
            builder.SetTrigger(completionGroup.Trigger);
            BackgroundTaskRegistration task </span>=<span> builder.Register();

            </span><span>return</span><span> downloader;
        }

        </span><span>//</span><span> 后台任务执行完成后弹出 toast 通知</span><span>private</span><span>void</span> ShowToast(<span>int</span> successTotal, <span>int</span><span> failureTotal)
        {
            </span><span>string</span> toastXml = $<span>@"</span><span>
                <toast activationType=‘foreground‘>
                    <visual>
                        <binding template=‘ToastGeneric‘>
                            <text>toast - title</text>
                            <text>下载任务成功数: {successTotal}</text>
                            <text>下载任务失败数: {failureTotal}</text>
                        </binding>
                    </visual>
                </toast></span><span>"</span><span>;

            XmlDocument toastDoc </span>= <span>new</span><span> XmlDocument();
            toastDoc.LoadXml(toastXml);

            ToastNotificationManager.CreateToastNotifier().Show(</span><span>new</span><span> ToastNotification(toastDoc));
        }
    }
}</span>

BackgroundTask/TransferModel.cs

            <span>/*</span>
            <span>
 * 扩展了 DownloadOperation 和 UploadOperation,用于 MVVM 绑定数据
 </span>
            <span>*/</span>
            <span>using</span>
            <span> System;
</span>
            <span>using</span>
            <span> System.ComponentModel;
</span>
            <span>using</span>
            <span> Windows.Networking.BackgroundTransfer;

</span>
            <span>namespace</span>
            <span> Windows10.BackgroundTask
{
    </span>
            <span>public</span>
            <span>class</span>
            <span> TransferModel : INotifyPropertyChanged
    {
        </span>
            <span>public</span> DownloadOperation DownloadOperation { <span>get</span>; <span>set</span><span>; }
        </span><span>public</span> UploadOperation UploadOperation { <span>get</span>; <span>set</span><span>; }

        </span><span>public</span><span>string</span> Source { <span>get</span>; <span>set</span><span>; }
        </span><span>public</span><span>string</span> Destination { <span>get</span>; <span>set</span><span>; }

        </span><span>private</span><span>string</span><span> _progress;
        </span><span>public</span><span>string</span><span> Progress
        {
            </span><span>get</span> { <span>return</span><span> _progress; }
            </span><span>set</span><span>
            {
                _progress </span>=<span> value;
                RaisePropertyChanged(</span><span>"</span><span>Progress</span><span>"</span><span>);
            }
        }

        </span><span>public</span><span>event</span><span> PropertyChangedEventHandler PropertyChanged;
        </span><span>protected</span><span>void</span> RaisePropertyChanged(<span>string</span><span> name)
        {
            </span><span>if</span> (PropertyChanged != <span>null</span><span>)
            {
                PropertyChanged(</span><span>this</span>, <span>new</span><span> PropertyChangedEventArgs(name));
            }
        }
    }
}</span>

BackgroundTask/TransferBackground.xaml

            <span><</span>
            <span>Page
    </span>
            <span>x:Class</span>
            <span>="Windows10.BackgroundTask.TransferBackground"</span>
            <span>
    xmlns</span>
            <span>="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
            <span>
    xmlns:x</span>
            <span>="http://schemas.microsoft.com/winfx/2006/xaml"</span>
            <span>
    xmlns:local</span>
            <span>="using:Windows10.BackgroundTask"</span>
            <span>
    xmlns:d</span>
            <span>="http://schemas.microsoft.com/expression/blend/2008"</span>
            <span>
    xmlns:mc</span>
            <span>="http://schemas.openxmlformats.org/markup-compatibility/2006"</span>
            <span>
    mc:Ignorable</span>
            <span>="d"</span>
            <span>></span>
            <span><</span>
            <span>Grid </span>
            <span>Background</span>
            <span>="Transparent"</span>
            <span>></span>
            <span><</span>
            <span>StackPanel </span>
            <span>Margin</span>
            <span>="10 0 10 10"</span>
            <span>></span>
            <span><</span>
            <span>ScrollViewer </span>
            <span>Name</span>
            <span>="scrollViewer"</span>
            <span> Height</span>
            <span>="100"</span>
            <span> Margin</span>
            <span>="5"</span>
            <span>></span>
            <span><</span>
            <span>TextBlock </span>
            <span>Name</span>
            <span>="lblMsg"</span>
            <span> TextWrapping</span>
            <span>="Wrap"</span>
            <span>/></span>
            <span></</span>
            <span>ScrollViewer</span>
            <span>></span>
            <span><</span>
            <span>Button </span>
            <span>Name</span>
            <span>="btnAddDownloadAndRegister"</span>
            <span> Content</span>
            <span>="新增一组(3 个)下载任务,并注册指定的后台任务,当这一组下载任务全部完成后触发一个后台任务。"</span>
            <span> Margin</span>
            <span>="5"</span>
            <span> Click</span>
            <span>="btnAddDownloadAndRegister_Click"</span>
            <span>/></span>
            <span><</span>
            <span>Button </span>
            <span>Name</span>
            <span>="btnRemoveDownloadAndUnregister"</span>
            <span> Content</span>
            <span>="取消下载任务并注销指定的后台任务"</span>
            <span> Margin</span>
            <span>="5"</span>
            <span> Click</span>
            <span>="btnRemoveDownloadAndUnregister_Click"</span>
            <span>/></span>
            <span><</span>
            <span>ListView </span>
            <span>Name</span>
            <span>="listView"</span>
            <span> Height</span>
            <span>="286"</span>
            <span> Padding</span>
            <span>="5"</span>
            <span>></span>
            <span><</span>
            <span>ListView.ItemTemplate</span>
            <span>></span>
            <span><</span>
            <span>DataTemplate</span>
            <span>></span>
            <span><</span>
            <span>StackPanel </span>
            <span>Margin</span>
            <span>="0 5"</span>
            <span> Background</span>
            <span>="Blue"</span>
            <span>></span>
            <span><</span>
            <span>TextBlock </span>
            <span>Text</span>
            <span>="</span>
            <span>{Binding Source}</span>
            <span>"</span>
            <span> Margin</span>
            <span>="5"</span>
            <span>/></span>
            <span><</span>
            <span>TextBlock </span>
            <span>Text</span>
            <span>="</span>
            <span>{Binding Destination}</span>
            <span>"</span>
            <span> Margin</span>
            <span>="5"</span>
            <span>/></span>
            <span><</span>
            <span>TextBlock </span>
            <span>Text</span>
            <span>="</span>
            <span>{Binding Progress}</span>
            <span>"</span>
            <span> Margin</span>
            <span>="5"</span>
            <span>/></span>
            <span></</span>
            <span>StackPanel</span>
            <span>></span>
            <span></</span>
            <span>DataTemplate</span>
            <span>></span>
            <span></</span>
            <span>ListView.ItemTemplate</span>
            <span>></span>
            <span></</span>
            <span>ListView</span>
            <span>></span>
            <span></</span>
            <span>StackPanel</span>
            <span>></span>
            <span></</span>
            <span>Grid</span>
            <span>></span>
            <span></</span>
            <span>Page</span>
            <span>></span>
        

BackgroundTask/TransferBackground.xaml.cs

            <span>/*</span>
            <span>
 * 演示后台下载任务的分组,以及组任务全部完成后如何触发后台任务
 * 
 * BackgroundTransferCompletionGroup - 分组对象(用于实现“组任务全部完成后触发后台任务”)
 *     Enable() - 启用“组任务全部完成后触发后台任务”的功能
 *     IsEnabled - 是否启用了“组任务全部完成后触发后台任务”的功能(只读)
 *     Trigger - “组任务全部完成后触发后台任务”的触发器
 *     
 * BackgroundDownloader - 后台下载任务管理器
 *     BackgroundDownloader(BackgroundTransferCompletionGroup completionGroup) - 通过指定的 BackgroundTransferCompletionGroup 对象实例化 BackgroundDownloader 对象
 *     CompletionGroup - 获取关联的 BackgroundTransferCompletionGroup 对象
 *     
 *     
 * 注:需要引用后台任务项目,相关代码参见 BackgroundTaskLib/BackgroundTaskTransfer.cs
 </span>
            <span>*/</span>
            <span>using</span>
            <span> BackgroundTaskLib;
</span>
            <span>using</span>
            <span> System;
</span>
            <span>using</span>
            <span> System.Collections.Generic;
</span>
            <span>using</span>
            <span> System.Collections.ObjectModel;
</span>
            <span>using</span>
            <span> System.Linq;
</span>
            <span>using</span>
            <span> System.Threading;
</span>
            <span>using</span>
            <span> System.Threading.Tasks;
</span>
            <span>using</span>
            <span> Windows.ApplicationModel.Background;
</span>
            <span>using</span>
            <span> Windows.Networking.BackgroundTransfer;
</span>
            <span>using</span>
            <span> Windows.Storage;
</span>
            <span>using</span>
            <span> Windows.UI.Core;
</span>
            <span>using</span>
            <span> Windows.UI.Xaml;
</span>
            <span>using</span>
            <span> Windows.UI.Xaml.Controls;
</span>
            <span>using</span>
            <span> Windows.UI.Xaml.Navigation;
</span>
            <span>using</span>
            <span> Windows.Web;

</span>
            <span>namespace</span>
            <span> Windows10.BackgroundTask
{
    </span>
            <span>public</span>
            <span>sealed</span>
            <span>partial</span>
            <span>class</span>
            <span> TransferBackground : Page
    {
        </span>
            <span>//</span>
            <span> 后台任务是否已在系统中注册</span>
            <span>private</span>
            <span>bool</span> _taskRegistered = <span>false</span><span>;

        </span><span>//</span><span> 下载任务的集合</span><span>private</span> ObservableCollection<TransferModel> _transfers = <span>new</span> ObservableCollection<TransferModel><span>();

        </span><span>//</span><span> 所有下载任务的关联的 CancellationTokenSource 对象</span><span>private</span> CancellationTokenSource _cancelToken = <span>new</span><span> CancellationTokenSource();

        </span><span>public</span><span> TransferBackground()
        {
            </span><span>this</span><span>.InitializeComponent();

            Init();
        }

        </span><span>private</span><span>async</span><span>void</span><span> Init()
        {
            listView.ItemsSource </span>=<span> _transfers;

            </span><span>//</span><span> 加载存在的下载任务</span><span>await</span><span> LoadDownloadAsync();
        }

        </span><span>//</span><span> 加载存在的下载任务</span><span>private</span><span>async</span><span> Task LoadDownloadAsync()
        {
            IReadOnlyList</span><DownloadOperation> downloads = <span>null</span><span>;
            </span><span>try</span><span>
            {
                </span><span>//</span><span> 获取存在的下载任务</span>
                downloads = <span>await</span><span> BackgroundDownloader.GetCurrentDownloadsAsync();
            }
            </span><span>catch</span><span> (Exception ex)
            {
                WriteLine(ex.ToString());
                </span><span>return</span><span>;
            }

            </span><span>if</span> (downloads.Count > <span>0</span><span>)
            {
                List</span><Task> tasks = <span>new</span> List<Task><span>();
                </span><span>foreach</span> (DownloadOperation download <span>in</span><span> downloads)
                {
                    </span><span>//</span><span> 监视指定的后台下载任务</span>
                    tasks.Add(HandleDownloadAsync(download, <span>false</span><span>));
                }

                </span><span>await</span><span> Task.WhenAll(tasks);
            }
        }

        </span><span>protected</span><span>override</span><span>void</span><span> OnNavigatedTo(NavigationEventArgs e)
        {
            </span><span>//</span><span> 遍历所有已注册的后台任务</span><span>foreach</span> (KeyValuePair<Guid, IBackgroundTaskRegistration> task <span>in</span><span> BackgroundTaskRegistration.AllTasks)
            {
                </span><span>if</span> (task.Value.Name ==<span> BackgroundTaskTransfer.TaskName)
                {
                    _taskRegistered </span>= <span>true</span><span>;
                    </span><span>break</span><span>;
                }
            }

            UpdateUI();
        }

        </span><span>//</span><span> 新增一组(3 个)下载任务,并注册指定的后台任务</span><span>private</span><span>async</span><span>void</span> btnAddDownloadAndRegister_Click(<span>object</span><span> sender, RoutedEventArgs e)
        {
            </span><span>//</span><span> 注册指定的后台任务,并返回与此后台任务相关联的 BackgroundDownloader 对象</span>
            BackgroundDownloader downloader =<span> BackgroundTaskTransfer.RegisterBackgroundTaskAndReturnBackgrounDownloader();
            _taskRegistered </span>= <span>true</span><span>;
            UpdateUI();

            List</span><DownloadOperation> downloads = <span>new</span> List<DownloadOperation><span>();
            </span><span>for</span> (<span>int</span> i = <span>0</span>; i < <span>3</span>; i++<span>)
            {
                Uri uri </span>= <span>new</span> Uri(<span>"</span><span>http://files.cnblogs.com/webabcd/Windows10.rar</span><span>"</span><span>);

                StorageFile destinationFile;
                </span><span>try</span><span>
                {
                    </span><span>//</span><span> 保存的目标地址(别忘了在 Package.appxmanifest 中配置好 <Capability Name="documentsLibrary" /> 和 .rar 类型文件的关联)</span>
                    StorageFolder storageFolder = <span>await</span> KnownFolders.GetFolderForUserAsync(<span>null</span><span>, KnownFolderId.DocumentsLibrary);
                    destinationFile </span>= <span>await</span> storageFolder.CreateFileAsync(<span>"</span><span>Windows10.rar</span><span>"</span><span>, CreationCollisionOption.GenerateUniqueName);
                }
                </span><span>catch</span><span> (Exception ex)
                {
                    WriteLine(ex.ToString());
                    </span><span>return</span><span>;
                }

                </span><span>//</span><span> 创建一个后台下载任务</span>
                DownloadOperation download =<span> downloader.CreateDownload(uri, destinationFile);

                downloads.Add(download);
            }

            </span><span>//</span><span> 启用“组任务全部完成后触发后台任务”的功能</span><span>            downloader.CompletionGroup.Enable();

            WriteLine(</span><span>"</span><span>用于完成后触发后台任务的一组下载任务创建完成了,相关的后台任务也注册了</span><span>"</span><span>);

            </span><span>//</span><span> 处理并监视组内的后台下载任务</span>
            Task[] tasks = <span>new</span><span> Task[downloads.Count];
            </span><span>for</span> (<span>int</span> i = <span>0</span>; i < downloads.Count; i++<span>)
            {
                tasks[i] </span>= HandleDownloadAsync(downloads[i], <span>true</span><span>);
            }

            </span><span>await</span><span> Task.WhenAll(tasks);
        }

        </span><span>///</span><span><summary></span><span>///</span><span> 处理并监视组内的后台下载任务
        </span><span>///</span><span></summary></span><span>///</span><span><param name="download"></span><span>后台下载任务</span><span></param></span><span>///</span><span><param name="isNew"></span><span>是否是新增的任务</span><span></param></span><span>private</span><span>async</span> Task HandleDownloadAsync(DownloadOperation download, <span>bool</span><span> isNew)
        {
            </span><span>try</span><span>
            {
                </span><span>//</span><span> 构造显示用的相关数据</span>
                TransferModel transfer = <span>new</span><span> TransferModel();
                transfer.DownloadOperation </span>=<span> download;
                transfer.Source </span>=<span> download.RequestedUri.ToString();
                transfer.Destination </span>=<span> download.ResultFile.Path;
                transfer.Progress </span>= download.Progress.Status.ToString() + <span>"</span><span>: 0 / 0</span><span>"</span><span>;

                _transfers.Add(transfer);

                WriteLine(</span><span>"</span><span>Task Count: </span><span>"</span> +<span> _transfers.Count.ToString());

                </span><span>//</span><span> 当下载进度发生变化时的回调函数</span>
                Progress<DownloadOperation> progressCallback = <span>new</span> Progress<DownloadOperation><span>(DownloadProgress);

                </span><span>if</span><span> (isNew)
                    </span><span>await</span> download.StartAsync().AsTask(_cancelToken.Token, progressCallback); <span>//</span><span> 启动一个后台下载任务</span><span>else</span><span>await</span> download.AttachAsync().AsTask(_cancelToken.Token, progressCallback); <span>//</span><span> 监视已存在的后台下载任务

                </span><span>//</span><span> 下载完成后获取服务端的响应信息</span>
                ResponseInformation response =<span> download.GetResponseInformation();
                WriteLine(</span><span>"</span><span>Completed: </span><span>"</span> + response.ActualUri + <span>"</span><span>, HttpStatusCode: </span><span>"</span> +<span> response.StatusCode.ToString());
            }
            </span><span>catch</span> (TaskCanceledException) <span>//</span><span> 调用 CancellationTokenSource.Cancel() 后会抛出此异常</span><span>            {
                WriteLine(</span><span>"</span><span>Canceled: </span><span>"</span> +<span> download.Guid);
            }
            </span><span>catch</span><span> (Exception ex)
            {
                </span><span>//</span><span> 将异常转换为 WebErrorStatus 枚举,如果获取到的是 WebErrorStatus.Unknown 则说明此次异常不是涉及 web 的异常</span>
                WebErrorStatus error =<span> BackgroundTransferError.GetStatus(ex.HResult);

                WriteLine(ex.ToString());
            }
            </span><span>finally</span><span>
            {
                _transfers.Remove(_transfers.First(p </span>=> p.DownloadOperation ==<span> download));
            }
        }

        </span><span>//</span><span> 进度发生变化时,更新 TransferModel 的 Progress</span><span>private</span><span>void</span><span> DownloadProgress(DownloadOperation download)
        {
            TransferModel transfer </span>= _transfers.First(p => p.DownloadOperation ==<span> download);
            transfer.Progress </span>= download.Progress.Status.ToString() + <span>"</span><span>: </span><span>"</span> + download.Progress.BytesReceived.ToString(<span>"</span><span>#,0</span><span>"</span>) + <span>"</span><span> / </span><span>"</span> + download.Progress.TotalBytesToReceive.ToString(<span>"</span><span>#,0</span><span>"</span><span>);
        }

        </span><span>//</span><span> 向 lblMsg 中追加一行文本</span><span>private</span><span>void</span> WriteLine(<span>string</span><span> message)
        {
            </span><span>var</span> ignore = lblMsg.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =><span>
            {
                lblMsg.Text </span>+=<span> message;
                lblMsg.Text </span>+=<span> Environment.NewLine;

                scrollViewer.ChangeView(</span><span>0</span><span>, scrollViewer.ScrollableHeight, 1f);
            });
        }

        </span><span>//</span><span> 取消下载任务并注销指定的后台任务</span><span>private</span><span>void</span> btnRemoveDownloadAndUnregister_Click(<span>object</span><span> sender, RoutedEventArgs e)
        {
            </span><span>//</span><span> 取消下载任务</span><span>            _cancelToken.Cancel();
            _cancelToken.Dispose();
            _cancelToken </span>= <span>new</span><span> CancellationTokenSource();

            </span><span>//</span><span> 注销指定的后台任务</span><span>foreach</span> (KeyValuePair<Guid, IBackgroundTaskRegistration> task <span>in</span><span> BackgroundTaskRegistration.AllTasks)
            {
                </span><span>if</span> (task.Value.Name ==<span> BackgroundTaskTransfer.TaskName)
                {
                    </span><span>//</span><span> 从系统中注销指定的后台任务。唯一一个参数代表如果当前后台任务正在运行中,是否需要将其取消</span>
                    task.Value.Unregister(<span>true</span><span>);
                    </span><span>break</span><span>;
                }
            }
            _taskRegistered </span>= <span>false</span><span>;
            UpdateUI();
        }

        </span><span>private</span><span>async</span><span>void</span><span> UpdateUI()
        {
            </span><span>await</span> Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =><span>
            {
                btnAddDownloadAndRegister.IsEnabled </span>= !<span>_taskRegistered;
                btnRemoveDownloadAndUnregister.IsEnabled </span>=<span> _taskRegistered;
            });
        }
    }
}</span>


OK
[源码下载]

原文:https://www.cnblogs.com/webabcd/p/9211759.html


【说明】本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!

相关教程推荐

其他课程推荐