c# - programa - ejecutar aplicaciones en segundo plano windows 10
UWP Background Task no se ejecuta después de 5 veces (2)
Estoy siguiendo https://docs.microsoft.com/en-us/windows/uwp/launch-resume/create-and-register-a-background-task document para crear una tarea en segundo plano que se ejecutará cada 15 minutos y ping un servicio.
Se creó un proyecto Windows Runtime Component con una clase sellada pública que implementó IBackgroundTask
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()); } } }
Entrada en el archivo Package.appmanifest de la aplicación UWP
<Extension Category="windows.backgroundTasks" EntryPoint="PeriodicBackgroundTask.FifteenMinutePeriodicTimer"> <BackgroundTasks> <Task Type="systemEvent" /> <Task Type="timer" /> </BackgroundTasks> </Extension>
Registro del temporizador al comienzo del método iniciado en App.xaml.cs
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."); } }
Después de instalar la aplicación, FifteenMinuteBackgroundTimer se ejecuta 5 o 6 veces. Algunas veces 5, a veces 6. Cuando trato de depurar la tarea usando Visual Studio, puedo depurarlo. No estoy seguro, por qué FifteenMinuteBackgroundTimer está muriendo después de 5 carreras. ¿Alguien puede decirme cómo puedo solucionar este problema?
Más información:
Construcción de Windows: 1607
Microsoft.NETCore.UniversalWindowsPlatform: 5.1.0
¿Alguien puede decirme cómo puedo solucionar este problema?
Después de registrar la tarea en segundo plano, la tarea de fondo se mostrará en la lista desplegable de la barra de herramientas de Lifecycle Events. Establezca un punto de interrupción en la tarea de fondo y luego haga clic en el nombre de fondo en la barra de herramientas; el estudio visual activará la tarea de fondo y podrá depurar. Más detalles por favor refiérase a Depurar una tarea en segundo plano .
por qué FifteenMinuteBackgroundTimer está muriendo después de 5 carreras.
Si ejecuta un código asíncrono en su tarea de fondo, su tarea en segundo plano debe usar un aplazamiento. Parece que crea la instancia de aplazamiento pero no obtuvo un aplazamiento de IBackgroundTaskInstance
. Por lo tanto, es posible que deba obtener el aplazamiento en primer lugar.
public void Run(IBackgroundTaskInstance taskInstance)
{
mDeferral = taskInstance.GetDeferral();
...
mDeferral.Complete();
}
Y es posible que no necesite Task.Delay(TimeSpan.FromSeconds(15)).Wait();
para agregar algún búfer para los procesos de sincronización para finalizar, ya que el aplazamiento puede ayudarlo a hacer esto. La tarea en segundo plano solo puede ejecutar 30s en total, en realidad el tiempo de ejecución puede ser solo de 25 segundos, si establece un retraso en la tarea de fondo puede provocar que no pueda completar la tarea y forzar el cierre.
Es muy probable que se encuentre con dos políticas relacionadas con el poder.
- Los disparos temporizadores periódicos se consideran oportunistas. Dependiendo de cuánta energía se utiliza en segundo plano (mientras no está encendida y apagada), es posible que su tarea no se active para ahorrar energía para otras actividades críticas del usuario (como recibir un SMS, presionar o una llamada entrante). Para verificar si esta es la condición en la que se está encontrando, puede alternar su aplicación a "siempre permitido" en el panel "configuración-> sistema-> batería-> batería por aplicación".
- También mencionó que la conexión en red no funciona cuando se ejecuta su disparador si la pantalla está apagada. En los sistemas en espera, debe especificar IsNetworkRequested como parte del registro del activador para que el sistema lleve la interfaz de red al modo operativo completo durante la duración de su tarea. Consulte la documentación aquí: https://docs.microsoft.com/en-us/uwp/api/Windows.ApplicationModel.Background.BackgroundTaskBuilder