2012-07-16 36 views
0

我使用http://software.tavlikos.com/2010/12/08/multitasking-in-ios-the-monotouch-way-part-i/文章的代碼示例在iOS應用程序DidEnterBackground事件上運行後臺任務。完成iOS後臺任務,前臺移動時

任務很重,很長的時間 - 接近1分鐘。如果用戶強制應用程序回到前臺,他應該等到任務完成。這有點弱。

我試圖用WillEnterForeground事件:

public override void WillEnterForeground (UIApplication application) 
    { 
     if (taskId != 0) { 
      Console.WriteLine("Finish previous task"); 
      application.EndBackgroundTask(taskId); 
      taskId = 0; 
     } 
    } 

但它調用任務結束。

如何在用戶切換到應用程序之前切斷後臺任務執行?

DidEnterBackground代碼:

public override void DidEnterBackground (UIApplication application) 
    { 
     Console.WriteLine ("DidEnterBackground"); 

     if (taskId != 0) { 
      Console.WriteLine("Finish previous task"); 
      application.EndBackgroundTask(taskId); 
      taskId = 0; 
     } 

     taskId = application.BeginBackgroundTask(delegate { 
      if (taskId != 0) { 
       application.EndBackgroundTask(taskId); 
       taskId = 0; 
      } 
     }); 

     Console.WriteLine("Begin task"); 
     application.InvokeOnMainThread(delegate() { 
      for(int i = 0; i < 700; i++) { 
       if ((i + 1) % 100 == 0) 
        Console.WriteLine("Time to remain: {0} seconds", application.BackgroundTimeRemaining); 
       //viewController.Touch(); 
      } 
     }); 

     application.EndBackgroundTask(taskId); 
     taskId = 0; 
    } 
+0

您好!你能否也請張貼你的DidEnterBackground方法? – 2012-07-16 10:22:53

+0

已更新。內在的任務是測試。我沒有發佈原始背景任務,該任務正在運行一分鐘左右。 – 2012-07-16 10:36:50

回答

2

的主要問題是,你的DidEnterBackground方法只有你的for循環完成(或者,您已經實現的任何任務)後返回,因爲你是在同一個線程調用它。使用InvokeOnMainThread與否,無關緊要,您的任務將在同一個線程上執行,實際上,您不需要致電InvokeOnMainThread,因爲您已經在主線程中。在正常情況下,這會導致您的應用被iOS終止。但是,由於您首先調用BeginBackgroundTask,因此不會發生。

如此以來,你DidEnterBackground方法的返回延遲,你把你的應用程序回到前臺在此期間,這是正常的要執行你的WillEnterForeground方法你的任務結束後。這是因爲方法尚未返回,因此WillEnterForeground方法無法執行,因此它在此之後排隊。

在我剛剛提到的上述文章中,我通過調用new System.Action(SomeDelegate(){}).BeginInvoke(null, null);來異步調用我的任務。您可以使用任何您喜歡的解決方案,我現在主要使用ThreadPool

所以,我會修改上述DidEnterBackground方法是這樣的:

public override void DidEnterBackground (UIApplication application) 
    { 
     Console.WriteLine ("DidEnterBackground"); 

     if (taskId != 0) { 
      Console.WriteLine("Finish previous task"); 
      application.EndBackgroundTask(taskId); 
      taskId = 0; 
     } 

     taskId = application.BeginBackgroundTask(delegate { 
      if (taskId != 0) { 
       application.EndBackgroundTask(taskId); 
       taskId = 0; 
      } 
     }); 

     Console.WriteLine("Begin task"); 
     ThreadPool.QueueUserWorkItem(delegate { 

      application.InvokeOnMainThread(delegate() { 
       for(int i = 0; i < 700; i++) { 
        if ((i + 1) % 100 == 0) 
         Console.WriteLine("Time to remain: {0} seconds", application.BackgroundTimeRemaining); 
        //viewController.Touch(); 
       } 

       // EndBackgroundTask must also be executed on the main thread. 
       application.EndBackgroundTask(taskId); 
       taskId = 0; 
      }); 

     }); 
    } 
+0

我可以使用AsyncCallback來啓動後臺任務嗎?嗯,我嘗試了新的DidEnterBackground - 是的,應用程序從DidEnterBackground退出,但WillEnterForeground不會啓動,直到任務完成。 – 2012-07-16 13:03:18