• 背水一战 Windows 10 (116)


    [源码下载]


    背水一战 Windows 10 (116) - 后台任务: 前台程序激活后台任务



    作者:webabcd


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

    • 前台程序激活后台任务



    示例
    演示后台任务的应用(前台程序激活后台任务)
    /BackgroundTaskLib/BackgroundTaskFore.cs

    /*
     * 后台任务,用于演示如何在前台程序通过 api 激活后台任务
     */
    
    using System;
    using System.Threading.Tasks;
    using Windows.ApplicationModel.Background;
    using Windows.Storage;
    
    namespace BackgroundTaskLib
    {
        // 实现 IBackgroundTask 接口,其只有一个方法,即 Run()
        public sealed class BackgroundTaskFore : IBackgroundTask
        {
            public async void Run(IBackgroundTaskInstance taskInstance)
            {
                // 后台任务在执行中被终止执行时所触发的事件
                taskInstance.Canceled += taskInstance_Canceled;
    
                // 异步操作
                BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
    
                try
                {
                    // 指定后台任务的进度
                    taskInstance.Progress = 0;
                    // taskInstance.InstanceId - 后台任务实例的唯一标识,由系统生成,与前台的 IBackgroundTaskRegistration.TaskId 一致
    
                    StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(@"webabcdBackgroundTaskfore.txt", CreationCollisionOption.ReplaceExisting);
                    for (uint progress = 10; progress <= 100; progress += 10)
                    {
                        await Task.Delay(1000);
    
                        // 更新后台任务的进度(会通知给前台)
                        taskInstance.Progress = progress;
    
                        // 写入相关数据到指定的文件
                        await FileIO.AppendTextAsync(file, "progress: " + progress.ToString() + ", currentTime: " + DateTime.Now.ToString() + Environment.NewLine);
                    }
                }
                finally
                {
                    // 完成异步操作
                    deferral.Complete();
                }
            }
    
            void taskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
            {
                /*
                 * BackgroundTaskCancellationReason - 后台任务在执行中被终止执行的原因
                 *     Abort - 前台 app 调用了 IBackgroundTaskRegistration.Unregister(true)
                 *     Terminating - 因为系统策略,而被终止
                 *     LoggingOff - 因为用户注销系统而被取消
                 *     ServicingUpdate - 因为 app 更新而被取消
                 *     ... - 还有好多,参见文档吧
                 */
            }
        }
    }

    BackgroundTask/Fore.xaml

    <Page
        x:Class="Windows10.BackgroundTask.Fore"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Windows10.BackgroundTask"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="Transparent">
            <StackPanel Margin="10 0 10 10">
    
                <TextBlock Name="lblMsg" Margin="5" />
    
                <Button Name="btnRegister" Content="注册一个后台任务" Margin="5" Click="btnRegister_Click" />
                <Button Name="btnUnregister" Content="注销指定的后台任务" Margin="5" Click="btnUnregister_Click" />
    
                <Button Name="btnRequest" Content="激活后台任务" Margin="5" Click="btnRequest_Click" />
    
            </StackPanel>
        </Grid>
    </Page>

    BackgroundTask/Fore.xaml.cs

    /*
     * 演示后台任务的应用(前台程序激活后台任务)
     *
     * 注:
     * 1、需要引用后台任务项目,相关代码参见 BackgroundTaskLib/BackgroundTaskFore.cs
     * 2、需要在 Package.appxmanifest 添加“后台任务”声明,支持的任务类型选择“常规”,并指定 EntryPoint(后台任务的类全名),类似如下:
     * <Extension Category="windows.backgroundTasks" EntryPoint="BackgroundTaskLib.BackgroundTaskFore">
     *   <BackgroundTasks>
     *     <Task Type="general" />
     *   </BackgroundTasks>
     * </Extension>
     */
    
    using System;
    using System.Collections.Generic;
    using Windows.ApplicationModel;
    using Windows.ApplicationModel.Background;
    using Windows.Storage;
    using Windows.UI.Core;
    using Windows.UI.Popups;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Navigation;
    
    namespace Windows10.BackgroundTask
    {
        public sealed partial class Fore : Page
        {
            // 所注册的后台任务的名称
            private string _taskName = "Fore";
    
            // 所注册的后台任务的 EntryPoint,即后台任务的类全名
            private string _taskEntryPoint = "BackgroundTaskLib.BackgroundTaskFore";
    
            // 后台任务是否已在系统中注册
            private bool _taskRegistered = false;
    
            // 后台任务执行状况的进度说明
            private string _taskProgress = "";
    
            // 实例化一个 ApplicationTrigger 类型的后台任务触发器(由前台程序通过 api 激活后台任务)
            private ApplicationTrigger applicationTrigger = new ApplicationTrigger();
    
            public Fore()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                // 遍历所有已注册的后台任务(避免重复注册)
                foreach (KeyValuePair<Guid, IBackgroundTaskRegistration> task in BackgroundTaskRegistration.AllTasks)
                {
                    if (task.Value.Name == _taskName)
                    {
                        // 如果找到了指定的后台任务,则为其增加 Progress 和 Completed 事件监听,以便前台 app 接收后台任务的进度汇报和完成汇报
                        AttachProgressAndCompletedHandlers(task.Value);
                        _taskRegistered = true;
                        break;
                    }
                }
    
                UpdateUI();
            }
    
            private async void btnRegister_Click(object sender, RoutedEventArgs e)
            {
                // 在注册后台任务之前,需要调用 BackgroundExecutionManager.RequestAccessAsync(),如果是更新过的 app 则在之前还需要调用 BackgroundExecutionManager.RemoveAccess()
                string appVersion = $"{Package.Current.Id.Version.Major}.{Package.Current.Id.Version.Minor}.{Package.Current.Id.Version.Build}.{Package.Current.Id.Version.Revision}";
                if ((string)ApplicationData.Current.LocalSettings.Values["AppVersion"] != appVersion)
                {
                    // 对于更新的 app 来说先要调用这个方法
                    BackgroundExecutionManager.RemoveAccess();
                    // 注册后台任务之前先要调用这个方法,并获取 BackgroundAccessStatus 状态
                    BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();
                    if (status == BackgroundAccessStatus.Unspecified || status == BackgroundAccessStatus.DeniedBySystemPolicy || status == BackgroundAccessStatus.DeniedByUser)
                    {
                        // 无权限注册后台任务
    
                        await new MessageDialog("没有权限注册后台任务").ShowAsync();
                    }
                    else
                    {
                        // 有权限注册后台任务
    
                        ApplicationData.Current.LocalSettings.Values["AppVersion"] = appVersion;
                    }
                }
    
    
                // 用于构造一个后台任务
                BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
                builder.Name = _taskName; // 后台任务的名称
                builder.TaskEntryPoint = _taskEntryPoint; // 后台任务入口点,即后台任务的类全名
                builder.SetTrigger(applicationTrigger);  // 指定后台任务的触发器类型为 ApplicationTrigger(由前台程序通过 api 激活后台任务)
    
                // 向系统注册此后台任务
                BackgroundTaskRegistration task = builder.Register();
    
                // 为此后台任务增加 Progress 和 Completed 事件监听,以便前台 app 接收后台任务的进度汇报和完成汇报
                AttachProgressAndCompletedHandlers(task);
    
                _taskRegistered = true;
    
                UpdateUI();
            }
    
            private void btnUnregister_Click(object sender, RoutedEventArgs e)
            {
                // 遍历所有已注册的后台任务
                foreach (KeyValuePair<Guid, IBackgroundTaskRegistration> task in BackgroundTaskRegistration.AllTasks)
                {
                    if (task.Value.Name == _taskName)
                    {
                        // 从系统中注销指定的后台任务。唯一一个参数代表如果当前后台任务正在运行中,是否需要将其取消
                        task.Value.Unregister(true);
                        break;
                    }
                }
    
                _taskRegistered = false;
    
                UpdateUI();
            }
    
            private async void btnRequest_Click(object sender, RoutedEventArgs e)
            {
                // 激活后台任务
                await applicationTrigger.RequestAsync();
            }
    
            private void AttachProgressAndCompletedHandlers(IBackgroundTaskRegistration task)
            {
                // 为任务增加 Progress 和 Completed 事件监听,以便前台 app 接收后台任务的进度汇报和完成汇报
                task.Progress += new BackgroundTaskProgressEventHandler(OnProgress);
                task.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);
            }
    
            private void OnProgress(IBackgroundTaskRegistration task, BackgroundTaskProgressEventArgs args)
            {
                // 获取后台任务的执行进度
                _taskProgress = args.Progress.ToString();
    
                UpdateUI();
            }
    
            private void OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args)
            {
                // 后台任务已经执行完成
                _taskProgress = "完成";
    
                // 如果此次后台任务的执行出现了错误,则调用 CheckResult() 后会抛出异常
                try
                {
                    args.CheckResult();
                }
                catch (Exception ex)
                {
                    _taskProgress = ex.ToString();
                }
    
                UpdateUI();
            }
    
            private async void UpdateUI()
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    btnRegister.IsEnabled = !_taskRegistered;
                    btnUnregister.IsEnabled = _taskRegistered;
    
                    if (_taskProgress != "")
                        lblMsg.Text = "进度:" + _taskProgress;
                });
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    字符串hash+回文树——hdu6599
    数位dp——牛客多校H
    线段树区间离散化——牛客多校E
    最小表示法——牛客多校第七场A
    后缀自动机求多串LCS——spojlcs2
    后缀自动机求LCS——spoj-LCS
    后缀自动机求字典序第k小的串——p3975
    后缀自动机模板——不同子串个数p2408
    同构图+思维构造——牛客多校第六场E
    封装,调用函数,以及参数化
  • 原文地址:https://www.cnblogs.com/webabcd/p/9211727.html
Copyright © 2020-2023  润新知