这个框架是我尝试替换标准库的 OperationQueue 和 Operation 类的努力。
过去在使用 OperationQueue
时,我遇到了一些问题,例如当它无法处理超过 100 个 Operation
时会无限期冻结(至少在 Linux 上是这样),以及许多其他令我感到沮丧或非常恼人的复杂之处。
所以我构建了这个!我尝试使其具有相同的线程安全性、类似的 API,但比标准库的同类更面向协议。
将其添加到您的 Package.swift
.package(url: "https://github.com/Ponyboy47/TaskKit.git", from: "0.6.0")
支持 Swift 4.x (包括 4.2)
TaskKit 的基础是(你猜对了)任务。
您可以遵循许多任务协议
这是所有后续 *Task
协议也遵循的基础协议。
为了遵循任何 Task
协议,您必须实现以下协议要求
var state: TaskState { get set }
这包含有关任务当前执行进度的信息,也可能包含日志消息数组(您需要在符合 Task
协议的对象中添加日志消息)。
建议您首先将其赋值为 .ready
,否则,请确保在将任务添加到任务队列 (TaskQueue) 之前 status.state
值是 .ready
,否则任务将无法执行。
var priority: TaskPriority { get set }
任务的优先级决定了它相对于队列中其他任务的执行时间。
高优先级任务在低优先级任务之前执行。
var qos: DispatchQoS { get }
这将是用于执行您的任务的 服务质量 (Quality of Service)。
func finish()
一个函数,无论您的任务是否成功完成,都会在任务完成时执行。
检查您的任务状态,以便您可以根据任务是失败还是成功来设置不同的逻辑。
func execute() -> Bool
这是将要调用以运行您的任务的函数。
此函数应返回您的任务是否成功完成执行。
一个 Task
,它依赖于某些外部源来正确配置自身(例如:在执行前验证配置文件的脚本)。
func configure() -> Bool
在您的任务可以执行之前必须成功运行的函数。
此函数应返回它是否正确配置了您的任务。
一个 Task
,可以在执行过程中停止并在稍后恢复。
func pause() -> Bool
用于停止执行的函数。
返回您的任务执行是否已成功暂停。
func resume() -> Bool
用于恢复先前停止的执行的函数。
返回您的任务执行是否已成功恢复。
一个 Task
,可以在执行过程中取消,但不能(或不会)在稍后恢复。
func cancel()
用于取消执行的函数。
一个 Task
,在成功执行一个或多个其他 Task
之前无法执行。
var dependencies: [Task] { get set }
必须在此任务开始执行之前成功执行的任务数组。
func finish(dependency: Task)
每当依赖项完成执行时运行的函数。
刚完成的依赖项作为 dependency
参数传递。
在您至少有一个类型符合任何 Task
协议之后,您可以创建一个 TaskQueue
并向其中添加任务
// Create a queue (maxSimultaneous defaults to 1)
let queue = TaskQueue(name: "com.example.taskqueue", maxSimultaneous: 2)
// Add a task to the queue
queue.add(task: myTask)
// Start the queue's execution
queue.start()
如果您有一个带有依赖项的任务,那么您不需要将依赖项添加到任务中。它们会在它们所依赖的任务运行之前自动运行。
// Add a dependency to your task
myTask.add(dependency: dependencyTask)
// Add the base task to the queue
queue.add(task: myTask)
// Start the queue
queue.start()
有时,您可能希望将任务分隔到不同的队列中,即使单独队列中的任务可能相互依赖。这是您可以改用 LinkedTaskQueue 的地方。
// Let's start with two queues:
// 1. For moving media files
// 2. For converting the media
let moveQueue = LinkedTaskQueue(name: "com.example.linked.move", maxSimultaneous: 5)
let conversionQueue = LinkedTaskQueue(name: "com.example.linked.conversion", linkedTo: moveQueue)
// Add our move tasks
moveQueue.add(tasks: moveTasks)
// One of the move tasks shouldn't happen until after it has been converted
moveTasks[0].add(dependency: conversionTask)
// Add that conversion task to its queue
conversionQueue.add(task: conversionTask)
// Start both the queues
moveQueue.start()
conversionQueue.start()
注意:任何依赖任务都必须存在于链接队列之一中,否则将发生致命错误
MIT