我有类似下面的代码,它使用后台任务在每15分钟运行一次的计时器上传数据。 什么都没有上传我的日志显示
WINDOWS SYNC SUCCESS:0m:0s:813ms
然而,如果实际上有数据上传,则需要更长的时间,最后我会得到2个日志
WINDOWS SYNC取消后:0m:25s:108ms - ExecutionTimeExceeded WINDOWS SYNC SUCCESS:0m:27s:617ms
我知道我在后台任务上只有25秒 - 但我的问题是为什么我的#34;最后"阻止在触发OnCancelled事件时执行?
这并不总是发生,这让我感到困惑。我经常得到取消的日志。 finally块总是会被调用吗?
另外 - 作为旁白 - 当我测试时,我在触发后台任务时让设备处于睡眠模式 - 不确定这是否相关。
public sealed class BackgroundSync : IBackgroundTask
{
CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
private DateTime startTime;
private DateTime endTime;
public async void Run(IBackgroundTaskInstance taskInstance)
{
BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();
// Associate a cancellation handler with the background task.
taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCancelled);
try
{
await Task.Run(async () =>
{
startTime = DateTime.Now;
// MY PROCESSSING IN HERE
endTime = DateTime.Now;
});
}
catch (Exception e)
{
await DataNAVToMobile.InsertBackgroundLog("WINDOWS SYNC EXCEPTION: " + e.Message);
}
finally
{
TimeSpan timeSpan = endTime - startTime;
await DataNAVToMobile.InsertBackgroundLog("WINDOWS SYNC SUCCESS: " + String.Format("{0}m:{1}s:{2}ms",timeSpan.Minutes,timeSpan.Seconds,timeSpan.Milliseconds));
_deferral.Complete();
}
}
private void OnCancelled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
// The background task has been detected as idle or hung.
// Cancel all pending async operations and return from the task.
endTime = DateTime.Now;
TimeSpan timeSpan = endTime - startTime;
DataNAVToMobile.InsertBackgroundLog("WINDOWS SYNC CANCELLED AFTER: " + String.Format("{0}m:{1}s:{2}ms", timeSpan.Minutes, timeSpan.Seconds, timeSpan.Milliseconds) + " - " + reason.ToString());
cancelTokenSource.Cancel();
}
答案 0 :(得分:2)
根据MSDN:
,后台任务限制为30秒后台任务仅限于30秒的挂钟使用时间。
您的后台任务在25收到取消通知,然后有5秒钟完成其工作并调用deferal.Complete方法。如果您拒绝取消以Run
方法运行的代码,则您的任务将在5秒后终止。
因此,我认为在您的情况下,您会收到取消通知,但运行方法中的代码会在不到5秒的时间内继续运行并达到finally
,并且您的任务成功完成而不会被终止。
请注意,取消令牌源不一定会立即取消run方法中的代码。您的代码可能处于取消令牌没有立即生效的位置。