首页 文章

UWP后台任务取消

提问于
浏览
0

我有下面的代码,它使用后台任务在每15分钟运行一次的计时器上传数据 . 什么都没有上传我的日志显示

WINDOWS SYNC SUCCESS: 0m:0s:813ms

但是,当实际上有数据要上传时,这需要更长的时间,最终我会得到2个日志

WINDOWS SYNC CANCELLED AFTER: 0m:25s:108ms - ExecutionTimeExceeded WINDOWS SYNC SUCCESS: 0m:27s:617ms

我知道我在后台任务上只有25秒 - 但是我的问题是为什么在触发OnCancelled事件时我的“finally”块被执行了?

这并不总是发生,这让我感到困惑 . 我经常得到取消的日志 . 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();
    }

1 回答

  • 1

    后台任务根据MSDN限制为30秒:

    后台任务仅限于30秒的挂钟使用 .

    您的后台任务在25收到取消通知,然后它有5秒钟完成其工作并调用deferal.Complete方法 . 如果您拒绝取消在 Run 方法中运行的代码,您的任务将在5秒后终止 .

    因此,我认为在您的情况下,您收到取消通知,但运行方法中的代码保持运行并在不到5秒内到达 finally ,您的任务成功完成而不会终止 .

    请注意,取消令牌源不一定会立即取消run方法中的代码 . 您的代码可能处于取消令牌没有立即生效的位置 .

相关问题