在页面导航上停止后台任务返回

时间:2016-09-06 22:01:50

标签: c# mvvm xamarin

我正在开发一个支持iOS和Android设备的Xamarin.Forms项目,我正在使用MVVM设计模式。

我有一个由ListView组成的导航根页面,当在此ListView上选择项目时,我执行以下命令导航到项目详细信息视图。

Page DetailsPage = new View.DetailsView(SelectedItemData);
await Navigation.PushAsync(DetailsPage);

打开此详细信息页面后,我开始运行后台任务。

private void StartBackgroundTask(){
    TimerBackgroundTask = new Timer((o) => {
         Device.BeginInvokeOnMainThread(() => Update()); }, null, 0, 1000);
    } 
}

哪个是基于这个类

public class Timer : CancellationTokenSource
{
    public bool IsDisposed { get; set; }
    public Timer(Action<object> callback, object state, int dueTime, int period)
    {
        System.Threading.Tasks.Task.Delay(dueTime, Token).ContinueWith(async (t, s) => 
        {
            Tuple<Action<object>, object> tuple = (Tuple<Action<object>, object>)s;

            while (!IsCancellationRequested)
            {
                await System.Threading.Tasks.Task.Run(() => tuple.Item1(tuple.Item2));
                await System.Threading.Tasks.Task.Delay(period);
            }
        },
        Tuple.Create(callback, state), CancellationToken.None,
        TaskContinuationOptions.ExecuteSynchronously | 
        TaskContinuationOptions.OnlyOnRanToCompletion,
        TaskScheduler.Default);
    }

    protected override void Dispose(bool disposing)
    {
        IsDisposed = true;
        if (disposing)
        {
            Cancel();
        }
        base.Dispose(disposing);
    }
}

更新功能每1秒更新一次UI。

一切正常并且应该没有问题,但是一旦我导航回根页面并返回到详细信息页面,问题就会开始出现 - 这样做两次会导致以下错误:

System.ArgumentException'jobject' must not be IntPtr.Zero. Parameter name: jobject

一旦StartBackgroundTask从代码中完全禁用,问题就会停止,因此我认为它是导致错误的人。此外,我相信这个后台任务继续在线程的某个地方运行,即使我导航回到根页面,我相信如果我能以某种方式处理后台任务OnDissapearing事件/导航后退按钮按下,错误将不再坚持。

不幸的是,我不知道如何以某种方式将命令绑定到导航后退按下事件,因为我的视图绑定到ViewModel。

任何提示都将不胜感激。

1 个答案:

答案 0 :(得分:1)

您可以通过覆盖OnDisappearing来检测是否正在关闭某个页面。在您的DetailPage中,您可以使用以下内容:

    protected override void OnDisappearing()
    {
        TimerBackgroundTask?.Dispose();
        base.OnDisappearing();
    }