我正在关注 https://learn.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-a-background-task文档以创建每 15 分钟运行一次并 ping 服务的后台任务。
使用实现 IBackgroundTask 的公共(public)密封类创建 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 版本:1607
Microsoft.NETCore.UniversalWindowsPlatform: 5.1.0
最佳答案
Can anybody please tell me how can I debug this issue?
注册后台任务后,您会发现后台任务显示在生命周期事件工具栏的下拉列表中。在后台任务上设置一个断点,然后点击工具栏中的后台名称,visual studio 将触发后台任务,您可以进行调试。更多详情请引用Debug a background task .
why FifteenMinuteBackgroundTimer is dying after 5 runs.
如果您在后台任务中运行任何异步代码,那么您的后台任务需要使用延迟。看起来您创建了延迟实例,但没有从 IBackgroundTaskInstance
获得延迟。因此,您可能需要先获得延期。
public void Run(IBackgroundTaskInstance taskInstance)
{
mDeferral = taskInstance.GetDeferral();
...
mDeferral.Complete();
}
而且您可能不需要 Task.Delay(TimeSpan.FromSeconds(15)).Wait();
来为异步进程添加一些缓冲区来完成,因为延迟可以帮助您做到这一点。后台任务总共只能运行30s,实际运行时间可能只有25s,如果在后台任务中设置延迟可能会导致无法完成任务而强制关闭。
关于c# - UWP 后台任务在 5 次后未运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42684650/