     /// Suspend if `result` satisfies `predicate` with specific queue.
     @discardableResult
     public func suspend(queue: DispatchQueue, where predicate: @escaping (Result) -> Bool) -> SDTask<Result> {
-        return self._apply(queue, suspend: predicate) { $0 }
+        let result = SDTask<Result>(queue: queue)
+        let worker = result.createWorker { self.result }
+        result.worker = worker
+        self.worker.notify(queue: queue) {
+            if !predicate(self.result) {
+                worker.perform()
+            }
+        }
+        return result
     }
 }
 


// MARK: SDTask

public class SDTask<Result> : SDAtomic {
    
    fileprivate var notify: [(Result) -> Void] = []
    
    fileprivate let lck = SDConditionLock()
    
    fileprivate var storage = Atomic<Result?>(value: nil)
    
    fileprivate init(queue: DispatchQueue, suspend: ((Result) -> Bool)?, block: @escaping () -> Result?) {
        super.init(queue: queue, block: SDTask.createBlock(suspend, block))
    }
    
    /// Create a SDTask and compute block.
    public init(queue: DispatchQueue = SDDefaultDispatchQueue, block: @escaping () -> Result) {
        super.init(queue: queue, block: SDTask.createBlock(nil, block))
        self.signal()
    }
}

private extension SDTask {
    
    @_transparent
    static func createBlock(_ suspend: ((Result) -> Bool)?, _ block: @escaping () -> Result?) -> (SDAtomic) -> Void {
        return { atomic in
            let _self = atomic as! SDTask<Result>
            if !_self.completed {
                guard let result = block() else { return }
                _self.lck.synchronized {
                    _self.storage.value = result
                    _self.lck.broadcast()
                }
            }
            let value = _self.storage.value!
            if suspend?(value) != true {
                _self.notify.forEach { $0(value) }
            }
            _self.notify = []
        }
    }
    
    @_transparent
    func _apply<R>(_ queue: DispatchQueue, suspend: ((R) -> Bool)?, block: @escaping (Result) -> R) -> SDTask<R> {
        var storage: Result?
        let task = SDTask<R>(queue: queue, suspend: suspend) { storage.map(block) }
        return lck.synchronized {
            if !completed {
                notify.append {
                    storage = $0
                    task.signal()
                }
            } else {
                storage = self.storage.value
                task.signal()
            }
            return task
        }
    }
}

    
    /// Result of task.
    public var result: Result {
        if let value = storage.value {
            return value
        }
        lck.wait(for: completed)
        return storage.value!
    }
}

