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



我正在尝试在我的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...");
}
}

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

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

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://learn.microsoft.com/en-us/windows/uwp/winrt-components/creating-windows-runtime-components-in-csharp-and-visual-basic

最新更新