2016-09-06 57 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