我正在关注https://docs.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-a-background-task文档以创建一个后台任务,每15分钟运行一次并ping服务。
使用实现IBackgroundTask
的公共密封类创建了一个Windows运行时组件项目namespace PeriodicBackgroundTask
{
public sealed class FifteenMinutePeriodicTimer : IBackgroundTask
{
private static readonly FileLogWriter mWriteLogToFile = new FileLogWriter();
public FifteenMinutePeriodicTimer() { }
public void Run(IBackgroundTaskInstance taskInstance)
{
try
{
taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);
mDeferral = taskInstance.GetDeferral();
mWriteLogToFile.log("Starting periodic timer at " + DateTime.Now.ToString());
// Calling method to do a Post call to a service.
mWriteLogToFile.log("Finishing periodic timer at " + DateTime.Now.ToString());
}
catch (Exception ex)
{
mWriteLogToFile.log("Fifteen Minute periodic timer failed.", ex);
}
finally
{
// Adding some buffer for async processes to finish.
Task.Delay(TimeSpan.FromSeconds(15)).Wait();
mDeferral.Complete();
}
}
private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
mWriteLogToFile.log("Fifteen minute periodic timer is canceled. {0}", reason.ToString());
}
}
}
在UWP应用程序的Package.appmanifest文件中输入
<Extension Category="windows.backgroundTasks" EntryPoint="PeriodicBackgroundTask.FifteenMinutePeriodicTimer">
<BackgroundTasks>
<Task Type="systemEvent" />
<Task Type="timer" />
</BackgroundTasks>
</Extension>
在App.xaml.cs中的OnLaunched方法开头注册计时器
public async static Task RegisterBackgroundTask()
{
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (String.Equals(task.Value.Name, TASK_NAME))
{
mWriteLogToFile.log("Old version of fifteen minute periodic timer found. Unregistering it.");
BackgroundExecutionManager.RemoveAccess();
// Unregistering so that any update in Background task can be applied.
task.Value.Unregister(true);
break;
}
}
BackgroundAccessStatus backgroundAccessStatus = await BackgroundExecutionManager.RequestAccessAsync();
if (backgroundAccessStatus == BackgroundAccessStatus.DeniedByUser ||
backgroundAccessStatus == BackgroundAccessStatus.DeniedBySystemPolicy)
{
mWriteLogToFile.log("Fifteen minute periodic timer registration failed, due to Request access status.");
return;
}
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
builder.Name = TASK_NAME;
builder.TaskEntryPoint = "PeriodicBackgroundTask.FifteenMinutePeriodicTimer";
builder.SetTrigger(new TimeTrigger(15, false));
builder.CancelOnConditionLoss = false;
var backgroundTask = builder.Register();
if (backgroundTask != null)
{
mWriteLogToFile.log("Fifteen minute periodic timer registration SUCCESSFUL.");
}
else
{
mWriteLogToFile.log("Fifteen minute periodic timer registration FAILED.");
}
}
安装应用程序后,FifteenMinuteBackgroundTimer运行5或6次。有时5,有时6.当我尝试使用Visual Studio调试任务时,我可以调试它。我不确定,为什么FifteenMinuteBackgroundTimer在5次运行后死亡。有人可以告诉我如何调试这个问题?
更多信息:
Windows Build:1607
Microsoft.NETCore.UniversalWindowsPlatform:5.1.0
答案 0 :(得分:4)
有人可以告诉我如何调试此问题?
注册后台任务后,您将在Lifecycle Events工具栏的下拉列表中找到后台任务。在后台任务上设置断点,然后单击工具栏中的背景名称,visual studio将触发后台任务,您可以进行调试。更多详情请参阅Debug a background task。
为什么FifteenMinuteBackgroundTimer在5次运行后死亡。
如果你在后台任务中运行任何异步代码,那么你的后台任务需要使用deferral.It好像你创建了延迟实例但没有从IBackgroundTaskInstance
推迟。所以你可能需要先推迟推迟。
public void Run(IBackgroundTaskInstance taskInstance)
{
mDeferral = taskInstance.GetDeferral();
...
mDeferral.Complete();
}
您可能不需要Task.Delay(TimeSpan.FromSeconds(15)).Wait();
为异步进程添加一些缓冲区来完成,因为延迟可以帮助您完成此操作。后台任务总共只能运行30s,实际上运行时间可能只有25s,如果在后台设置延迟任务可能导致无法完成任务并强行关闭。
答案 1 :(得分:1)
您很可能遇到两项与电力相关的政策。