在task中使用队列queue

2023-01-27  本文已影响0人  松龄学编程
class Duck{
    
    func walk() async {
        //do something
        print("walk start")
        try? await Task.sleep(nanoseconds: UInt64(2e9))
        print("walk end")
    }
    
    func quack() async {
        //do something...
        print("quack start")
        try? await Task.sleep(nanoseconds: UInt64(2e9))
        print("quack end")
    }
    
    func fly() async{
        //do something
        print("fly start")
        try? await Task.sleep(nanoseconds: UInt64(2e9))
        print("fly end")
    }
    
}

let duck = Duck()

//Task{
//    await duck.walk()
//}
//
//Task{
//    await duck.quack()
//}
//
//Task{
//    await duck.fly()
//}

class TaskQueue{
    
    private actor TaskQueueActor{
        private var blocks : [() async -> Void] = []
        private var currentTask : Task<Void,Never>? = nil
        
        func addBlock(block:@escaping () async -> Void){
            blocks.append(block)
            next()
        }
        
        func next()
        {
            if(currentTask != nil) {
                return
            }
            if(!blocks.isEmpty)
            {
                let block = blocks.removeFirst()
                currentTask = Task{
                    await block()
                    currentTask = nil
                    next()
                }
            }
        }
    }
    private let taskQueueActor = TaskQueueActor()
    
    func dispatch(block:@escaping () async ->Void){
        Task{
            await taskQueueActor.addBlock(block: block)
        }
    }
}

let queue = TaskQueue()
queue.dispatch {
    await duck.walk()
}

queue.dispatch {
    await duck.quack()
}

queue.dispatch {
    await duck.fly()
}

结果是顺序执行:

walk start
walk end
quack start
quack end
fly start
fly end

上一篇下一篇

猜你喜欢

热点阅读