UWP - 无头应用程序在 3 或 4 小时后停止
UWP - Headless app stops after 3 or 4 hours
我有一个无头 UWP 应用程序,它应该每 10 分钟从传感器获取数据并将其发送到云端。
当我 运行 来自 Raspberry Pi 上无头应用程序的代码时,它会在 3 或 4 小时后停止测量,没有错误(我有很多日志)。正好是三四个小时。如果我在 8 点、11 点或 12 点启动应用程序,它就会停止...
它似乎已停止,因为我有在测试中运行良好的取消令牌,但在这里它不再触发。在设备门户的应用程序管理器上,该应用程序似乎是 运行ning。
我还在设备门户的“性能”页面中注意到,在测量期间内存下降了大约 8 MB。
最重要的是 运行 我 运行 在 RPi 和笔记本电脑上使用了来自 headed 应用程序的相同代码,并且运行良好。它连续工作了 16 多个小时,直到我停止它。在笔记本电脑和 RPi 上都没有内存问题,应用程序在整个期间使用相同数量的 RAM。
当 运行作为无头应用程序时,什么会导致此行为?
以下是我如何从无头应用调用代码:
BackgroundTaskDeferral deferral;
private ISettingsReader settings;
private ILogger logger;
private IFlowManager<PalmSenseMeasurement> flow;
private IServiceProvider services;
IBackgroundTaskInstance myTaskInstance;
public async void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.Canceled += TaskInstance_Canceled;
deferral = taskInstance.GetDeferral();
myTaskInstance = taskInstance;
try
{
SetProperties();
var flowTask = flow.RunFlowAsync();
await flowTask;
}
catch (Exception ex)
{
logger.LogCritical("#####---->Exception occured in StartupTask (Run): {0}", ex.ToString());
}
}
private void SetProperties()
{
services = SensorHubContainer.Services;
settings = services.GetService<ISettingsReader>();
flow = services.GetService<IFlowManager<PalmSenseMeasurement>>();
logger = services.GetService<ILogger<StartupTask>>();
}
private void TaskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
logger.LogDebug("StartupTask.TaskInstance_Canceled() - {0}", reason.ToString());
deferral.Complete();
}
下面是我如何从 headed 应用调用代码:
private async Task GetMeasurementsAsync()
{
try
{
flow = services.GetService<IFlowManager<PalmSenseMeasurement>>();
await flow.RunFlowAsync();
}
catch (Exception ex)
{
Measurements.Add(new MeasurementResult() { ErrorMessage = ex.Message });
}
}
RunFlowAsync 方法如下所示:
public async Task RunFlowAsync()
{
var loopInterval = settings.NoOfSecondsForLoopInterval;
while (true)
{
try
{
logger.LogInformation("Starting a new loop in {0} seconds...", loopInterval);
//check for previous unsent files
await resender.TryResendMeasuresAsync();
await Task.Delay(TimeSpan.FromSeconds(loopInterval));
await DoMeasureAndSend();
logger.LogInformation("Loop finished");
}
catch (Exception ex)
{
logger.LogError("Error in Flow<{0}>! Error {1}", typeof(T).FullName, ex);
#if DEBUG
Debug.WriteLine(ex.ToString());
#endif
}
}
}
问题出在我必须使用的第 3 方库,并且必须以不同于无头应用程序的方式调用它。
如果 SynchronizationContext.Current 为空,它会在内部创建自己的 TaskScheduler。
我有一个无头 UWP 应用程序,它应该每 10 分钟从传感器获取数据并将其发送到云端。 当我 运行 来自 Raspberry Pi 上无头应用程序的代码时,它会在 3 或 4 小时后停止测量,没有错误(我有很多日志)。正好是三四个小时。如果我在 8 点、11 点或 12 点启动应用程序,它就会停止...
它似乎已停止,因为我有在测试中运行良好的取消令牌,但在这里它不再触发。在设备门户的应用程序管理器上,该应用程序似乎是 运行ning。
我还在设备门户的“性能”页面中注意到,在测量期间内存下降了大约 8 MB。
最重要的是 运行 我 运行 在 RPi 和笔记本电脑上使用了来自 headed 应用程序的相同代码,并且运行良好。它连续工作了 16 多个小时,直到我停止它。在笔记本电脑和 RPi 上都没有内存问题,应用程序在整个期间使用相同数量的 RAM。
当 运行作为无头应用程序时,什么会导致此行为?
以下是我如何从无头应用调用代码:
BackgroundTaskDeferral deferral;
private ISettingsReader settings;
private ILogger logger;
private IFlowManager<PalmSenseMeasurement> flow;
private IServiceProvider services;
IBackgroundTaskInstance myTaskInstance;
public async void Run(IBackgroundTaskInstance taskInstance)
{
taskInstance.Canceled += TaskInstance_Canceled;
deferral = taskInstance.GetDeferral();
myTaskInstance = taskInstance;
try
{
SetProperties();
var flowTask = flow.RunFlowAsync();
await flowTask;
}
catch (Exception ex)
{
logger.LogCritical("#####---->Exception occured in StartupTask (Run): {0}", ex.ToString());
}
}
private void SetProperties()
{
services = SensorHubContainer.Services;
settings = services.GetService<ISettingsReader>();
flow = services.GetService<IFlowManager<PalmSenseMeasurement>>();
logger = services.GetService<ILogger<StartupTask>>();
}
private void TaskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
logger.LogDebug("StartupTask.TaskInstance_Canceled() - {0}", reason.ToString());
deferral.Complete();
}
下面是我如何从 headed 应用调用代码:
private async Task GetMeasurementsAsync()
{
try
{
flow = services.GetService<IFlowManager<PalmSenseMeasurement>>();
await flow.RunFlowAsync();
}
catch (Exception ex)
{
Measurements.Add(new MeasurementResult() { ErrorMessage = ex.Message });
}
}
RunFlowAsync 方法如下所示:
public async Task RunFlowAsync()
{
var loopInterval = settings.NoOfSecondsForLoopInterval;
while (true)
{
try
{
logger.LogInformation("Starting a new loop in {0} seconds...", loopInterval);
//check for previous unsent files
await resender.TryResendMeasuresAsync();
await Task.Delay(TimeSpan.FromSeconds(loopInterval));
await DoMeasureAndSend();
logger.LogInformation("Loop finished");
}
catch (Exception ex)
{
logger.LogError("Error in Flow<{0}>! Error {1}", typeof(T).FullName, ex);
#if DEBUG
Debug.WriteLine(ex.ToString());
#endif
}
}
}
问题出在我必须使用的第 3 方库,并且必须以不同于无头应用程序的方式调用它。 如果 SynchronizationContext.Current 为空,它会在内部创建自己的 TaskScheduler。