     
     /// Run `block` after `self` is completed with specific queue.
     @discardableResult
-    public func then<R>(queue: DispatchQueue, block: @escaping (Result) -> R) -> SDTask<R> {
+    public func then<R>(queue: DispatchQueue, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], block: @escaping (Result) -> R) -> SDTask<R> {
         let result = SDTask<R>(queue: queue)
-        let worker = result.createWorker { block(self.result) }
+        let worker = result.createWorker(qos: qos, flags: flags) { block(self.result) }
         result.worker = worker
         self.worker.notify(queue: queue, execute: worker)
         return result


/// Create a SDTask and compute block.
@discardableResult
public func async<Result>(queue: DispatchQueue = SDDefaultDispatchQueue, _ block: @escaping () -> Result) -> SDTask<Result> {
    return SDTask(queue: queue, block: block)
}

    
    /// Suspend if `result` satisfies `predicate` with specific queue.
    @discardableResult
    public func suspend(queue: DispatchQueue, qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], where predicate: @escaping (Result) -> Bool) -> SDTask<Result> {
        let result = SDTask<Result>(queue: queue)
        let worker = result.createWorker(qos: qos, flags: flags) { self.result }
        result.worker = worker
        self.worker.notify(qos: qos, flags: flags, queue: queue) {
            if !predicate(self.result) {
                worker.perform()
            }
