如何使用Dispatch或Operation队列动态更改后台操作优先级。

时间:2013-09-10 12:51:35

标签: ios multithreading grand-central-dispatch nsthread nsoperationqueue

这是我遇到的问题。在应用程序运行时,我有几个任务要在后台完成。当我通过将它们推送到并发调度队列来在后台运行这些任务时,需要10秒以上才能完成所有这些任务。它们基本上从磁盘加载数据并解析它并将结果表示给用户。这就是它们只是缓存结果并极大地改善了用户体验。

此缓存结果用于应用程序内部的特定功能,并且在打开应用程序后不立即使用该功能时,加载支持该功能的数据需要10秒才会出现问题,因为用户决定使用它,已经加载了数据。

但是当用户在打开它后立即在应用程序中输入该功能时,需要相当长的时间(从用户的角度来看)加载数据。此外,在同一时刻不需要整个数据,而是在给定时刻它的一部分。 这就是为什么我们需要同时加载数据,如果可能的话尽快带来结果。这就是我决定将数据分成块的原因,当用户请求数据时,我们应该通过后台线程加载相应的块,并为该线程赋予最高优先级。我会解释我的意思。

想象一下,有100个数据,加载它们需要10秒以上。每当用户第一次查询数据时,应用程序就会确定用户需要哪个数据块并开始加载该数据块。加载该部分之后,剩余数据也将在后台加载,以便以后查询更快(没有加载缓存的延迟)。但是这里出现了一个问题,当用户决定在他已经输入一个查询后立即更改查询,并且该更改发生在例如数据加载过程的第二秒(请记住加载数据需要10秒以上,我们仍然有超过8秒的时间来完成加载过程),然后在极端情况下,用户将收到他的数据,等待所有数据都被加载。这就是我需要以某种方式管理后台任务的执行。也就是说,当用户更改输入时,我应该更改执行的优先级,并给予加载相应块的线程最高优先级而不停止它,这样它将获得更多的处理器时间,并将更快地完成,并将结果传递给用户更快,比我保留优先级相同。我知道我可以为队列分配优先级。但有没有一种方法可以在它们仍在执行时动态地更改它们? 或者我是否需要实现自定义线程管理,以实现这些行为?我真的不想深入了解线程管理,如果可以仅使用调度或操作队列来实现,我将很高兴。

我希望我已经很好地描述了这个问题。如果不是,请评论下面的不清楚,我会解释。

非常感谢您阅读到目前为止:)特别感谢能够提供答案的人。非常特别感谢一个人,他将使用调度或操作队列给我解决方案:)))

2 个答案:

答案 0 :(得分:1)

我认为你需要放弃思考队列运行的优先级(这对你所描述的场景来说听起来不是很重要),更多的是考虑如何使用Dispatch I / O或者甚至更简单的Dispatch源来控制数据的读取方式。正如你所说,加载数据需要10秒钟,如果用户在询问后立即突然改变查询,你需要基本上停止读取前一个请求的数据并做任何需要做的事情来完成最新的查询。使用Dispatch I / O来块化数据(异步)并异步更新UI将允许您在流中改变主意(使用某种信号量或取消标记)并继续涓流数据(你不要)如果用户改变主意,请说明该数据是否仍然有用),暂停阅读过程,或完全取消并开始新的操作。通过这种方式,能够暂停/恢复一个源并为相当小的数据块进行激活回调,肯定能让你在比8秒钟更精细的时间内做出决定!

答案 1 :(得分:0)

我担心唯一的办法是在开始新操作之前取消正在运行的操作。 在完成或取消之前,您无法将其从队列中删除。

作为对您的问题的改进,我建议加载一些东西,即使用户在后台不需要它们 - 所以你可以在缓存之后加载它们。

您可以创建2个具有2个不同优先级的NSOperationQueue,并在用户在LowPriorityQueue上空闲时在后台下载内容。对于重要的操作,您可以拥有高优先级队列 - 每次搜索项更改时都会取消该队列。

除此之外,您只需要缓存这两个队列的结果。