2012-07-16 30 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