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

C# 如何在Windows运行时组件(UWP)中调用RequestAccessAsync(),c#,uwp,async-await,C#,Uwp,Async Await,我试图在我的UWP项目中创建一个后台任务,我遵循了MSDN的文档,但我不明白如何在RegisterBackgroundTask函数中等待RequestAccessAsync()任务。这是我在m y Windows运行时组件项目中的BackgroundTask类: public sealed class BackgroundTask : IBackgroundTask { // Note: defined at class scope so we can mark it complete

我试图在我的UWP项目中创建一个后台任务,我遵循了MSDN的文档,但我不明白如何在RegisterBackgroundTask函数中等待RequestAccessAsync()任务。这是我在m y 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...");
    }
}
public密封类BackgroundTask:IBackgroundTask
{
//注意:在类作用域中定义,因此如果选择支持取消,我们可以在OnCancel()回调中将其标记为complete
私人背景任务延期(延期);;
private BackgroundTaskCancellationReason\u cancelReason=BackgroundTaskCancellationReason.Abort;
私有易失性bool\u cancelrequest=false;
公共无效运行(IBackgroundTaskInstance taskInstance)
{
taskInstance.Task.Completed+=taskInstance\u OnCompleted;
taskInstance.cancelled+=taskInstance\u oncancelled;
_延迟=taskInstance.getDeleral();
//
//TODO:插入代码以使用
//等待关键字,例如:
//
//等待ExampleMethodAsync();
//
_延迟。完成();
}
//
//使用指定的taskEntryPoint、name、trigger、,
//和条件(可选)。
//
//taskEntryPoint:后台任务的任务入口点。
//taskName:后台任务的名称。
//触发器:后台任务的触发器。
//条件:可选参数。条件事件必须为true才能激发任务。
//
公共静态异步任务注册表BackgroundTask(
字符串taskEntryPoint,
字符串taskName,
IBackgroundTrigger触发器,
iBackground条件)
{
//
//检查此后台任务的现有注册。
//
foreach(BackgroundTaskRegistration.AllTasks中的var cur)
{
if(cur.Value.Name==taskName)
{
//
//任务已注册。
//
返回(BackgroundTaskRegistration)(当前值);
}
}
//
//注册后台任务。
//
var builder=新背景任务生成器
{
名称=任务名称,
TaskEntryPoint=TaskEntryPoint
};
builder.SetTrigger(触发器);
if(条件!=null)
{
builder.AddCondition(条件);
}
var access=await BackgroundExecutionManager.RequestAccessAsync();
if(access!=BackgroundAccessStatus.AlwaysAllowed&&access!=BackgroundAccessStatus.AllowedSubjectToSystemPolicy)
{
返回默认值(BackgroundTaskRegistration);
}
var task=builder.Register();
//
//将已完成的处理程序与任务注册关联。
//
task.Completed+=新的BackgroundTaskCompletedEventHandler(已注册\未完成);
返回任务;
}
私有静态无效已注册\未完成(IBackgroundTaskRegistration任务、BackgroundTaskCompletedEventArgs args args)
{
var settings=Windows.Storage.ApplicationData.Current.LocalSettings;
var key=task.TaskId.ToString();
var message=settings.Values[key].ToString();
//更新(信息);
}
私有void任务实例未完成(BackgroundTaskRegistration发件人、BackgroundTaskCompletedEventArgs args args)
{
}
private void TaskInstance\u OnCanceled(IBackgroundTaskInstance发送方,BackgroundTaskCancellationReason)
{
//
//指示后台任务已取消。
//
_取消请求=真;
_取消原因=原因;
Debug.WriteLine(“后台”+sender.Task.Name+“取消请求…”);
}
}
我总是遇到以下编译错误:

错误WME1039:方法“DigitalArtisan.Background.BackgroundTask.RegisterBackgroundTask(System.String,System.String,Windows.ApplicationModel.Background.IBackgroundTrigger,Windows.ApplicationModel.Background.IBackgroundCondition)”的签名中具有“System.Threading.Tasks.Task”类型的参数。尽管此泛型类型不是有效的Windows运行时类型,但该类型或其泛型参数实现的接口是有效的Windows运行时类型。考虑将方法签名中的类型“任务”改为以下类型之一:WINDOWS.Fuff.IasycActudio、WINDOWS.Buffig.IASYNC操作,或者其他Windows运行时异步接口之一。当使用Windows运行时异步接口时,标准的.NET等待模式也适用。有关将托管任务对象转换为Windows运行时异步接口的详细信息,请参阅System.Runtime.InteropServices.WindowsRuntime.AsyncInfo

任务
不是WinRT类型<代码>IAsyncOperation是:

public static async IAsyncOperation<BackgroundTaskRegistration> RegisterBackgroundTask(
    string taskEntryPoint,
    string taskName,
    IBackgroundTrigger trigger,
    IBackgroundCondition condition)
公共静态异步IAsyncOperation寄存器backgroundTask(
字符串taskEntryPoint,
字符串taskName,
IBackgroundTrigger触发器,
iBackground条件)

Windows运行时组件的所有公共方法都必须返回WinRT类型。请参阅以下博文,以了解有关此问题以及如何包装任务的更多信息:

//public方法返回一个IAsyncOperation,该IAsyncOperation封装了返回.NET任务的私有方法:
公共静态异步IAsyncOperation寄存器BackgroundTask(
字符串taskEntryPoint,
字符串taskName,
IBackgroundTrigger触发器,
iBackground条件)
{
返回注册表BackgroundTask(taskEntryPoint、taskName、触发器、条件);
}
//将当前方法更改为私有方法:
专用静态异步任务注册表BackgroundTask(
字符串taskEntryPoint,
字符串taskName,
IBackgroundTrigger触发器,
iBackground条件)
{
//...
}
<
//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)
{
    //...
}