如何在Windows运行时组件(UWP)中调用RequestAccessAsync()

时间:2018-01-25 15:57:15

标签: c# uwp async-await

我正在尝试在我的UWP项目中创建后台任务,我已经按照MSDN中的文档进行了操作,但是我不知道如何从中查找RequestAccessAsync()任务。 RegisterBackgroundTask函数。这是我的Windows运行时组件项目中的BackgroundTask类:

public sealed class BackgroundTask : IBackgroundTask
{
    // Note: defined at class scope so we can mark it complete inside the OnCancel() callback if we choose to support cancellation
    private BackgroundTaskDeferral _deferral;
    private BackgroundTaskCancellationReason _cancelReason = BackgroundTaskCancellationReason.Abort;
    private volatile bool _cancelRequested = false;

    public void Run(IBackgroundTaskInstance taskInstance)
    {
        taskInstance.Task.Completed += TaskInstance_OnCompleted;
        taskInstance.Canceled += TaskInstance_OnCanceled;

        _deferral = taskInstance.GetDeferral();

        //
        // TODO: Insert code to start one or more asynchronous methods using the
        //       await keyword, for example:
        //
        // await ExampleMethodAsync();
        //

        _deferral.Complete();
    }

    //
    // Register a background task with the specified taskEntryPoint, name, trigger,
    // and condition (optional).
    //
    // taskEntryPoint: Task entry point for the background task.
    // taskName: A name for the background task.
    // trigger: The trigger for the background task.
    // condition: Optional parameter. A conditional event that must be true for the task to fire.
    //
    public static async Task<BackgroundTaskRegistration> RegisterBackgroundTask(
        string taskEntryPoint,
        string taskName,
        IBackgroundTrigger trigger,
        IBackgroundCondition condition)
    {
        //
        // Check for existing registrations of this background task.
        //
        foreach (var cur in BackgroundTaskRegistration.AllTasks)
        {

            if (cur.Value.Name == taskName)
            {
                //
                // The task is already registered.
                //
                return (BackgroundTaskRegistration)(cur.Value);
            }
        }

        //
        // Register the background task.
        //
        var builder = new BackgroundTaskBuilder
        {
            Name = taskName,
            TaskEntryPoint = taskEntryPoint
        };

        builder.SetTrigger(trigger);

        if (condition != null)
        {
            builder.AddCondition(condition);
        }

        var access = await BackgroundExecutionManager.RequestAccessAsync();

        if (access != BackgroundAccessStatus.AlwaysAllowed && access != BackgroundAccessStatus.AllowedSubjectToSystemPolicy)
        {
            return default(BackgroundTaskRegistration);
        }

        var task = builder.Register();

        //
        // Associate a completed handler with the task registration.
        //
        task.Completed += new BackgroundTaskCompletedEventHandler(Registered_OnCompleted);

        return task;
    }

    private static void Registered_OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args)
    {
        var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
        var key = task.TaskId.ToString();
        var message = settings.Values[key].ToString();
        //UpdateUI(message);
    }

    private void TaskInstance_OnCompleted(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
    {
    }

    private void TaskInstance_OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
    {
        //
        // Indicate that the background task is canceled.
        //
        _cancelRequested = true;
        _cancelReason = reason;

        Debug.WriteLine("Background " + sender.Task.Name + " Cancel Requested...");
    }
}

我总是遇到以下编译错误:

  

错误WME1039:Method&#39; DigitalArtisan.Background.BackgroundTask.RegisterBackgroundTask(System.String,System.String,Windows.ApplicationModel.Background.IBackgroundTrigger,Windows.ApplicationModel.Background.IBackgroundCondition)&#39;有一个参数类型为System.Threading.Tasks.Task&#39;在它的签名。虽然此泛型类型不是有效的Windows运行时类型,但类型或其泛型参数实现的是有效Windows运行时类型的接口。考虑更改类型&#39;任务&#39;在方法签名中改为以下类型之一:Windows.Foundation.IAsyncAction,Windows.Foundation.IAsyncOperation或其他Windows运行时异步接口之一。使用Windows运行时异步接口时,标准.NET awaiter模式也适用。有关将托管任务对象转换为Windows运行时异步接口的详细信息,请参阅System.Runtime.InteropServices.WindowsRuntime.AsyncInfo。

1 个答案:

答案 0 :(得分:2)

Task<T>不是WinRT类型。 IAsyncOperation<T>是:

public static async IAsyncOperation<BackgroundTaskRegistration> RegisterBackgroundTask(
    string taskEntryPoint,
    string taskName,
    IBackgroundTrigger trigger,
    IBackgroundCondition condition)

...

Windows运行时组件的所有公共方法都必须返回WinRT类型。有关此内容以及如何包装任务的更多信息,请参阅以下博客文章: http://dotnetbyexample.blogspot.se/2014/11/returning-task-from-windows-runtime.html

//the public method returns an IAsyncOperation<T> that wraps the private method that returns a .NET Task<T>:
public static async IAsyncOperation<BackgroundTaskRegistration> RegisterBackgroundTask(
string taskEntryPoint,
string taskName,
IBackgroundTrigger trigger,
IBackgroundCondition condition)
{
    return RegisterBackgroundTask(taskEntryPoint, taskName, trigger, condition).AsAsyncOperation();
}

//change your current method to be private:
private static async Task<BackgroundTaskRegistration> RegisterBackgroundTask(
    string taskEntryPoint,
    string taskName,
    IBackgroundTrigger trigger,
    IBackgroundCondition condition)
{
    //...
}

MSDN上的以下文档也应该有所帮助:https://docs.microsoft.com/en-us/windows/uwp/winrt-components/creating-windows-runtime-components-in-csharp-and-visual-basic