重新想象 Windows 8 Store Apps (28) - 选取器: CachedFileUpdater(缓存文件更新程序)

简介: 原文:重新想象 Windows 8 Store Apps (28) - 选取器: CachedFileUpdater(缓存文件更新程序)[源码下载] 重新想象 Windows 8 Store Apps (28) - 选取器: CachedFileUpdater(缓存文件更新程序) 作者:web...
原文: 重新想象 Windows 8 Store Apps (28) - 选取器: CachedFileUpdater(缓存文件更新程序)

[源码下载]


重新想象 Windows 8 Store Apps (28) - 选取器: CachedFileUpdater(缓存文件更新程序)



作者:webabcd


介绍
重新想象 Windows 8 Store Apps 之 选取器

  • CachedFileUpdater - 缓存文件更新程序



示例
一、首先新建一个 Windows 应用商店项目,使其作为缓存文件更新程序

1、 打开一个文件,并关联到 CachedFileUpdater
CachedFileUpdaterProvider/MyOpenPicker.xaml

<Page
    x:Class="CachedFileUpdaterProvider.MyOpenPicker"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CachedFileUpdaterProvider"
    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="120 0 0 0">

            <TextBlock Name="lblMsg" FontSize="14.667" />

            <Button Name="btnPickCachedFileLocal" Content="提供一个由 Local 更新的 CachedFile(由 CachedFileUpdater 更新 CachedFile)" Click="btnPickCachedFileLocal_Click_1" Margin="0 10 0 0" />

            <Button Name="btnPickCachedFileRemote" Content="提供一个由 Remote 更新的 CachedFile(由 app 更新 CachedFile)" Click="btnPickCachedFileRemote_Click_1" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>
</Page>

CachedFileUpdaterProvider/MyOpenPicker.xaml.cs

/*
 * 打开一个文件,并关联到 CachedFileUpdater
 * 
 * 1、在 Package.appxmanifest 中新增一个“文件打开选取器”声明,并做相关配置
 * 2、在 App.xaml.cs 中 override void OnFileOpenPickerActivated(FileOpenPickerActivatedEventArgs args),如果 app 是由文件打开选取器激活的,则可以在此获取其相关信息
 */

using System;
using Windows.ApplicationModel.Activation;
using Windows.Storage;
using Windows.Storage.Pickers.Provider;
using Windows.Storage.Provider;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace CachedFileUpdaterProvider
{
    public sealed partial class MyOpenPicker : Page
    {
        private FileOpenPickerUI _fileOpenPickerUI;

        public MyOpenPicker()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            var args = (FileOpenPickerActivatedEventArgs)e.Parameter;
            _fileOpenPickerUI = args.FileOpenPickerUI;

            _fileOpenPickerUI.Title = "自定义文件打开选取器";
        }

        // 本 CachedFile 用于从 Local 更新
        private async void btnPickCachedFileLocal_Click_1(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(@"webabcdCachedFileUpdaterLocal.txt", CreationCollisionOption.ReplaceExisting);
            string textContent = "I am webabcd";

            await FileIO.WriteTextAsync(file, textContent);

            /*
             * 设置 CachedFile,即将文件关联到 CachedFileUpdater
             * SetUpdateInformation(IStorageFile file, string contentId, ReadActivationMode readMode, WriteActivationMode writeMode, CachedFileOptions options);
             *     file - 与 CachedFileUpdater 关联的文件
             *     contentId - 与 CachedFileUpdater 关联的文件标识
             */
            CachedFileUpdater.SetUpdateInformation(file, "cachedFileLocal", ReadActivationMode.BeforeAccess, WriteActivationMode.NotNeeded, CachedFileOptions.RequireUpdateOnAccess);

            lblMsg.Text = "选择的文件: " + file.Name;
            AddFileResult result = _fileOpenPickerUI.AddFile("myFile", file);
        }

        // 本 CachedFile 用于从 Remote 更新
        private async void btnPickCachedFileRemote_Click_1(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(@"webabcdCachedFileUpdaterRemote.txt", CreationCollisionOption.ReplaceExisting);
            string textContent = "I am webabcd";

            await FileIO.WriteTextAsync(file, textContent);

            /*
             * 设置 CachedFile,即将文件关联到 CachedFileUpdater
             * SetUpdateInformation(IStorageFile file, string contentId, ReadActivationMode readMode, WriteActivationMode writeMode, CachedFileOptions options);
             *     file - 与 CachedFileUpdater 关联的文件
             *     contentId - 与 CachedFileUpdater 关联的文件标识
             */
            CachedFileUpdater.SetUpdateInformation(file, "cachedFileRemote", ReadActivationMode.NotNeeded, WriteActivationMode.AfterWrite, CachedFileOptions.RequireUpdateOnAccess);

            lblMsg.Text = "选择的文件: " + file.Name;
            AddFileResult result = _fileOpenPickerUI.AddFile("myFile", file);
        }
    }
}


2、 开发自定义缓存文件更新程序
CachedFileUpdaterProvider/MyCachedFileUpdater.xaml

<Page
    x:Class="CachedFileUpdaterProvider.MyCachedFileUpdater"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CachedFileUpdaterProvider"
    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="120 0 0 0">

            <TextBlock Name="lblMsg" FontSize="14.667" />

            <Button Name="btnUpdate" Content="更新 CachedFile(由 CachedFileUpdater 更新 CachedFile)" Click="btnUpdate_Click_1" Margin="0 10 0 0" />

        </StackPanel>
    </Grid>
</Page>

CachedFileUpdaterProvider/MyCachedFileUpdater.xaml.cs

/*
 * 演示如何开发自定义缓存文件更新程序
 * 
 * 1、在 Package.appxmanifest 中新增一个“缓存文件更新程序”声明,并做相关配置
 * 2、在 App.xaml.cs 中 override void OnCachedFileUpdaterActivated(CachedFileUpdaterActivatedEventArgs args),如果 app 是由文件打开选取器激活的,则可以在此获取其相关信息
 * 
 * CachedFileUpdaterActivatedEventArgs - 通过“缓存文件更新程序”激活应用程序时的事件参数
 *     CachedFileUpdaterUI - 获取 CachedFileUpdaterUI 对象
 *     PreviousExecutionState, Kind, SplashScreen - 各种激活 app 的方式的事件参数基
 * 
 * CachedFileUpdaterUI - 缓存文件更新程序的帮助类
 *     Title - 将在“缓存文件更新程序”上显示的标题
 *     UIStatus - “缓存文件更新程序”的 UI 状态(Unavailable, Hidden, Visible, Complete)
 *     UpdateTarget - Local 代表由 CachedFileUpdater 更新; Remote 代表由 app 更新
 *     UIRequested - 需要显示“缓存文件更新程序”的 UI 时触发的事件
 *     FileUpdateRequested - 当 app 激活缓存文件更新程序时,会触发 FileUpdateRequested 事件(事件参数:CachedFileUpdaterActivatedEventArgs)
 *     
 * CachedFileUpdaterActivatedEventArgs
 *     Request - 返回 FileUpdateRequest 类型的对象
 *     
 * FileUpdateRequest
 *     File - 关联的文件
 *     ContentId - 关联的文件标识
 *     Status - 文件的更新状态(FileUpdateStatus 枚举。Incomplete, Complete, UserInputNeeded, CurrentlyUnavailable, Failed, CompleteAndRenamed)
 *     GetDeferral() - 获取异步操作对象,同时开始异步操作,之后通过 Complete() 通知完成异步操作
 */

using System;
using Windows.ApplicationModel.Activation;
using Windows.Storage;
using Windows.Storage.Provider;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace CachedFileUpdaterProvider
{
    public sealed partial class MyCachedFileUpdater : Page
    {
        private CachedFileUpdaterUI _cachedFileUpdaterUI;
        private FileUpdateRequest _fileUpdateRequest;
        private CoreDispatcher _dispatcher = Windows.UI.Xaml.Window.Current.Dispatcher;

        public MyCachedFileUpdater()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // 获取 CachedFileUpdaterUI 对象
            var args = (CachedFileUpdaterActivatedEventArgs)e.Parameter;
            _cachedFileUpdaterUI = args.CachedFileUpdaterUI;

            _cachedFileUpdaterUI.Title = "缓存文件更新程序";

            _cachedFileUpdaterUI.FileUpdateRequested += _cachedFileUpdaterUI_FileUpdateRequested;
            _cachedFileUpdaterUI.UIRequested += _cachedFileUpdaterUI_UIRequested;
        }

        // 需要显示 CachedFileUpdater 的 UI 时(即当 FileUpdateRequest.Status 等于 UserInputNeeded 时),会调用此事件处理器
        async void _cachedFileUpdaterUI_UIRequested(CachedFileUpdaterUI sender, object args)
        {
            await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                Windows.UI.Xaml.Window.Current.Content = this;
                lblMsg.Text = "FileUpdateStatus: " + _fileUpdateRequest.Status.ToString();
            });
        }

        void _cachedFileUpdaterUI_FileUpdateRequested(CachedFileUpdaterUI sender, FileUpdateRequestedEventArgs args)
        {
            _fileUpdateRequest = args.Request;
            FileUpdateRequestDeferral fileUpdateRequestDeferral = _fileUpdateRequest.GetDeferral();

            if (_cachedFileUpdaterUI.UpdateTarget == CachedFileTarget.Local) // 由 CachedFileUpdater 更新 CachedFile(CachedFileTarget.Local 方式)
            {
                // 显示 CachedFileUpdater 的 UI
                if (_cachedFileUpdaterUI.UIStatus == UIStatus.Hidden)
                {
                    _fileUpdateRequest.Status = FileUpdateStatus.UserInputNeeded;
                    fileUpdateRequestDeferral.Complete();
                }
            }
            else if (_cachedFileUpdaterUI.UpdateTarget == CachedFileTarget.Remote) // 由 app 更新 CachedFile(CachedFileTarget.Remote 方式)
            {
                // CachedFileUpdater 返回给 app 一个 FileUpdateStatus 状态
                _fileUpdateRequest.Status = FileUpdateStatus.Complete;
                fileUpdateRequestDeferral.Complete();
            }
        }

        private async void btnUpdate_Click_1(object sender, RoutedEventArgs e)
        {
            FileUpdateRequestDeferral fileUpdateRequestDeferral = _fileUpdateRequest.GetDeferral();

            // 由 CachedFileUpdater 更新 CachedFile,然后返回给 app 一个 FileUpdateStatus 状态
            await FileIO.AppendTextAsync(_fileUpdateRequest.File, Environment.NewLine + "由 CachedFileUpdater 更新:" + DateTime.Now.ToString());

            string fileContent = await FileIO.ReadTextAsync(_fileUpdateRequest.File);

            lblMsg.Text = "文件名: " + _fileUpdateRequest.File.Name;
            lblMsg.Text += Environment.NewLine;
            lblMsg.Text += "文件内容: " + fileContent;

            _fileUpdateRequest.Status = FileUpdateStatus.Complete;
            fileUpdateRequestDeferral.Complete();

            btnUpdate.IsEnabled = false;
        }
    }
}


3、判断程序是否是由文件打开选取器激活或者是否是由缓存文件更新程序激活
App.xaml.cs

// 通过文件打开选取器激活应用程序时所调用的方法
protected override void OnFileOpenPickerActivated(FileOpenPickerActivatedEventArgs args)
{
    var rootFrame = new Frame();
    rootFrame.Navigate(typeof(MyOpenPicker), args);
    Window.Current.Content = rootFrame;

    Window.Current.Activate();
}

// 通过缓存文件更新程序(CachedFileUpdater)激活应用程序时所调用的方法
protected override void OnCachedFileUpdaterActivated(CachedFileUpdaterActivatedEventArgs args)
{
    var rootFrame = new Frame();
    rootFrame.Navigate(typeof(MyCachedFileUpdater), args);
    Window.Current.Content = rootFrame;

    Window.Current.Activate();
}



二、在 app 中调用 CachedFileUpdater

1、演示如何调用 CachedFileUpdater(缓存文件更新程序)
Picker/CachedFileUpdaterDemo.xaml

<Page
    x:Class="XamlDemo.Picker.CachedFileUpdaterDemo"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlDemo.Picker"
    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="120 0 0 0">

            <TextBlock Name="lblMsg" FontSize="14.667" />

            <Button Name="btnGetCachedFile" Content="打开 Provider 提供的 CachedFile" Click="btnGetCachedFile_Click_1" Margin="0 10 0 0" />

            <Button Name="btnReadCachedFile" Content="由 CachedFileUpdater 更新文件" Click="btnReadCachedFile_Click_1" Margin="0 10 0 0" />

            <Button Name="btnWriteCachedFile" Content="由 app 更新文件" Click="btnWriteCachedFile_Click_1" Margin="0 10 0 0" />
            
        </StackPanel>
    </Grid>
</Page>

Picker/CachedFileUpdaterDemo.xaml.cs

/*
 * 演示如何调用 CachedFileUpdater(缓存文件更新程序)
 * 
 * 流程:
 * 1、单击“打开 Provider 提供的 CachedFile”按钮,以弹出打开文件对话框
 * 2、在弹出的对话框中选择 CachedFileUpdaterProvider,以打开 CachedFileUpdaterProvider 项目中的 MyOpenPicker.xaml
 * 3、在 provider 中单击“提供一个 CachedFile”按钮,以打开一个文件,同时将此文件关联到 CachedFileUpdater
 * 4、如果在 provider 选择了“提供一个由 Local 更新的 CachedFile”则转到(5);如果在 provider 选择了“提供一个由 Remote 更新的 CachedFile”则转到(6)
 * 
 * 5、单击“由 CachedFileUpdater 更新文件”按钮,激活 CachedFileUpdater,获取由 CachedFileUpdater 修改后的文件(CachedFileUpdater 的 Local 方式)
 * 6、单击“由 app 更新文件”按钮,会在 app 端更指定的 CachedFile,需要的话可以激活 CachedFileUpdater 做一些别的处理(CachedFileUpdater 的 Remote 方式)
 * 
 * 
 * 注:app 代表调用方,provider 代表缓存文件提供方,CachedFileUpdater 代表缓存文件更新程序
 */

using System;
using Windows.Storage;
using Windows.Storage.AccessCache;
using Windows.Storage.Pickers;
using Windows.Storage.Provider;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace XamlDemo.Picker
{
    public sealed partial class CachedFileUpdaterDemo : Page
    {
        private string _cachedFileToken;

        public CachedFileUpdaterDemo()
        {
            this.InitializeComponent();
        }

        private async void btnGetCachedFile_Click_1(object sender, RoutedEventArgs e)
        {
            if (XamlDemo.Common.Helper.EnsureUnsnapped())
            {
                FileOpenPicker openPicker = new FileOpenPicker();
                openPicker.FileTypeFilter.Add(".txt");

                // 弹出打开文件对话框后,选择 CachedFileUpdaterProvider,以获取 CachedFile
                StorageFile file = await openPicker.PickSingleFileAsync();
                if (file != null)
                {
                    _cachedFileToken = StorageApplicationPermissions.FutureAccessList.Add(file);
                    string fileContent = await FileIO.ReadTextAsync(file);

                    lblMsg.Text = "文件名: " + file.Name;
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += "文件内容: " +  fileContent;
                }
                else
                {
                    lblMsg.Text = "取消了";
                }
            }
        }

        // 由 CachedFileUpdater 更新文件(CachedFileUpdater 的 Local 方式)
        private async void btnReadCachedFile_Click_1(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrEmpty(_cachedFileToken))
            {
                StorageFile file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(_cachedFileToken);
                string fileContent = await FileIO.ReadTextAsync(file);

                lblMsg.Text = "文件名: " + file.Name;
                lblMsg.Text += Environment.NewLine;
                lblMsg.Text += "文件内容: " + fileContent;
            }
        }

        // 由 app 更新文件(CachedFileUpdater 的 Remote 方式)
        private async void btnWriteCachedFile_Click_1(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrEmpty(_cachedFileToken))
            {
                StorageFile file = await StorageApplicationPermissions.FutureAccessList.GetFileAsync(_cachedFileToken);

                // 开始异步更新操作(不需要激活 CachedFileUpdater 的话可以不走这一步)
                CachedFileManager.DeferUpdates(file);
                
                // 更新文件
                await FileIO.AppendTextAsync(file, Environment.NewLine + "由 app 更新:" + DateTime.Now.ToString());

                // 通知系统已完成异步操作(之前激活的 CachedFileUpdater 会返回一个 FileUpdateStatus)
                FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file);

                lblMsg.Text = status.ToString();
                lblMsg.Text += Environment.NewLine;

                if (status == FileUpdateStatus.Complete)
                {
                    string fileContent = await FileIO.ReadTextAsync(file);

                    lblMsg.Text += "文件名: " + file.Name;
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += "文件内容: " + fileContent;
                }
            }
        }
    }
}



OK
[源码下载]

目录
相关文章
|
2月前
|
存储 开发框架 .NET
Windows IIS中asp的global.asa全局配置文件使用说明
Windows IIS中asp的global.asa全局配置文件使用说明
39 1
|
2月前
|
Java Windows
如何在windows上运行jar包/JAR文件 如何在cmd上运行 jar包 保姆级教程 超详细
本文提供了一个详细的教程,解释了如何在Windows操作系统的命令提示符(cmd)中运行JAR文件。
993 1
|
3月前
|
Windows Python
python获取windows机子上运行的程序名称
python获取windows机子上运行的程序名称
|
2月前
|
安全 API C#
C# 如何让程序后台进程不被Windows任务管理器强制结束
C# 如何让程序后台进程不被Windows任务管理器强制结束
66 0
|
2月前
|
程序员 Windows
程序员必备文件搜索工具 Everything 带安装包!!! 比windows自带的文件搜索快几百倍!!! 超级好用的文件搜索工具,仅几兆,不占内存,打开即用
文章推荐了程序员必备的文件搜索工具Everything,并提供了安装包下载链接,强调其比Windows自带搜索快且占用内存少。
48 0
|
3月前
|
安全 网络安全 API
基于WMI更新Windows系统信息采集程序sysInfo的一些收获
基于WMI更新Windows系统信息采集程序sysInfo的一些收获
|
3月前
|
Windows
7-3|windows删除目录下的所有文件的命令
7-3|windows删除目录下的所有文件的命令
|
2月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
78 6
|
21天前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
22天前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构