2016-09-06 60 views
0

我正在研究支持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); 
    } 
} 

更新功能更新UI每隔1秒。

这里的一切工作正常,因为它应该没有问题,但问题的开始,一旦我导航回到根页面出现,并返回到详细信息页面 - 这样做两次导致以下错误:

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

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

不幸的是,我不知道我如何或甚至可能以某种方式绑定命令导航返回按下的事件,因为我的视图绑定到ViewModel。

任何提示将不胜感激。

回答

1

您可以通过覆盖OnDisappearing来检测页面是否被解散。在你DetailPage你可以有这样的事情:

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

这whas我的想法也一样,但是它从来没有上即使我从Page类继承了我的ViewModel执行。将不得不再次尝试。 – OverflowStack

+0

你的ViewModel不会得到回调。这个方法的调用由Xamarin.Forms调用。如果你想拦截你的ViewModel中的回调,那么你将不得不公开一个将从ContentPage中继回调的命令。所以在OnDisappearing你的内容页面中,你会有这样的行为:ViewModel.OnDisapperaingCommand.Execute() – wishmaster