完成iOS后台任务,将其移至前台
Posted
技术标签:
【中文标题】完成iOS后台任务,将其移至前台【英文标题】:Finish iOS background task, when move it foreground 【发布时间】:2012-07-16 09:22:53 【问题描述】:我使用来自http://software.tavlikos.com/2010/12/08/multitasking-in-ios-the-monotouch-way-part-i/ 文章的代码示例在 iOS 应用程序 DidEnterBackground 事件上运行后台任务。
任务繁重且耗时长 - 将近 1 分钟。如果用户强制应用程序回到前台,他应该等到任务完成。有点弱。
我尝试使用 WillEnterForeground 事件:
public override void WillEnterForeground (UIApplication application)
if (taskId != 0)
Console.WriteLine("Finish previous task");
application.EndBackgroundTask(taskId);
taskId = 0;
但它会调用 任务结束。
如果用户在完成之前切换到应用程序,如何中断后台任务执行?
DidEnter后台代码:
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;
【问题讨论】:
您好!您能否也发布您的 DidEnterBackground 方法? 已更新。内部任务是为了测试。我没有发布运行近一分钟的原始后台任务。 【参考方案1】:主要问题是您的 DidEnterBackground
方法仅在您的 for 循环完成(或您已实现的任何任务)后才会返回,因为您在同一个线程上调用它。是否使用InvokeOnMainThread
没关系,您的任务将在同一个线程上执行,实际上,您不需要调用InvokeOnMainThread
,因为您已经在主线程上。在正常情况下,这会导致您的应用程序被 iOS 终止。但是,由于您首先调用 BeginBackgroundTask,因此不会发生这种情况。
因此,由于您的 DidEnterBackground
方法的返回被延迟,并且您同时将您的应用程序带回前台,所以您的 WillEnterForeground
方法在您的任务结束后执行是正常的。那是因为WillEnterForeground
方法还没有返回,所以DidEnterBackground
方法还没有返回,所以无法执行,所以在后面排队。
在您提到的上述文章中的示例中,我通过调用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;
);
);
【讨论】:
我可以使用例如 AsyncCallback 来启动后台任务吗?嗯,我尝试了新的 DidEnterBackground - 是的,应用程序从 DidEnterBackground 中退出,但 WillEnterForeground 在任务完成之前不会触发。以上是关于完成iOS后台任务,将其移至前台的主要内容,如果未能解决你的问题,请参考以下文章