UWP 后台任务 - 应用程序触发器 - 当文件已存在时无法创建文件

Posted

技术标签:

【中文标题】UWP 后台任务 - 应用程序触发器 - 当文件已存在时无法创建文件【英文标题】:UWP Background Task - Application Trigger - Cannot create a file when that file already exists 【发布时间】:2018-05-02 02:37:28 【问题描述】:

在 UWP 中,我试图按需创建一个简单的后台任务。所以当我点击一个按钮时,我想要一个后台任务启动并在后台处理一些文件。

以下是我的基本任务代码:

public class BackgroundSyncService

    private ApplicationTrigger trigger = new ApplicationTrigger();

    public async Task Start()
    
        if (IsRegistered())
            Deregister();

        BackgroundExecutionManager.RemoveAccess();

        // does this prompt everytime?
        await BackgroundExecutionManager.RequestAccessAsync();

        var builder = new BackgroundTaskBuilder();

        builder.Name = "BackgroundTask";
        builder.TaskEntryPoint = typeof(BackgroundTask).FullName;

        builder.SetTrigger(trigger);
        BackgroundTaskRegistration task = builder.Register();

        task.Completed += Task_Completed;

        var result = await trigger.RequestAsync();
    

    private void Task_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
    
        // alert UI
    

    public void Stop()
    
        Deregister();
    

    private void Deregister()
    
        var taskName = "BackgroundTask";

        foreach (var task in BackgroundTaskRegistration.AllTasks)
            if (task.Value.Name == taskName)
                task.Value.Unregister(true);
    

    private bool IsRegistered()
    
        var taskName = "BackgroundTask";

        foreach (var task in BackgroundTaskRegistration.AllTasks)
            if (task.Value.Name == taskName)
                return true;

        return false;
    

当代码命中builder.Register() 时,它会抛出以下异常:

System.Exception: '当该文件已存在时无法创建该文件。 (来自 HRESULT 的异常:0x800700B7)'

不确定我在这里做错了什么或者这个错误在后台任务的上下文中意味着什么?

【问题讨论】:

【参考方案1】:

对于您的问题,这是因为您在创建文件时,当前文件夹中已经存在具有指定名称的文件。您可以尝试在创建文件时指定NameCollisionOption。

var file = await ApplicationData.Current.LocalFolder.
    CreateFileAsync("MyFile", CreationCollisionOption.ReplaceExisting);

作为您的示例项目中的代码,您使用了ApplicationData.LocalSettings,当您添加设置键时,您应该检查该键是否存在。

var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
if (!settings.Values.ContainsKey("BackgroundTask"))

    settings.Values.Add("BackgroundTask", "Hello from UWP");

或者您可以使用ApplicationData.LocalSettings 如下来使用密钥并更改其值,

var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
settings.Values["BackgroundTask"] = "Hello from UWP";

您也可以查看Store and retrieve settings and other app data 主题。

【讨论】:

感谢您的回答。但是,即使在完全卸载 UWP 应用程序并重新部署 VS 之后,我也看到了这种行为。如果这很重要,这是一个 Xamarin Forms 应用程序。它确实跳过了“IsRegistered”调用,因此它绝对不会在首次加载新应用时注册。 我无法在我身边重现此问题。我在回答中使用了该场景,我不会再次收到错误消息。你能提供一个最低限度的样本来帮助我了解你的问题吗? @aherrick 我上面的答案已经修改了,大家可以看看试试看。 我不明白你在说这段代码吗? github.com/aherrick/XFormsOfflineSync/blob/master/…我把那段代码注释掉了 但是如果我直接运行您的项目而不做任何更改,它在我这边运行良好,不会发生任何错误。【参考方案2】:

我正在使用 ApplicationTrigger 进行 BackgroundTask 注册,并在重新注册之前创建 ApplicationTrigger 的新实例为我修复了此错误。

【讨论】:

以上是关于UWP 后台任务 - 应用程序触发器 - 当文件已存在时无法创建文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UWP 的后台每天午夜运行一些代码?

UWP:为啥我的后台任务(使用 TimeTrigger)会超出 CPU 配额?

UWP -- Background Task 深入解析

UWP 后台任务系统关闭

我们可以使用应用程序触发器自动调用后台任务吗?

在现代待机模式下触发后台任务