简体   繁体   中英

Waiting for a task to finish before moving on to next one

I'm using NMSSH in order to connect to a server and then grab data off that server. However, connecting to the server, performing commands, and retrieving the data all take time to complete. Previously, I was using sleep() commands in order to allow the program to pause and let those commands finish running but if I don't specify the exact amount of time to sleep the data may not fully finish downloading (since the data varies in size its hard to determine the correct amount of sleep). So after doing some research it seemed that Dispatch Groups and Async operations were the correct way to go. I implemented these as follows:

let queue = DispatchQueue(label: "myqueue")
let group = DispatchGroup()    
let myfirstconnection: SSH = SSH()
myfirstconnection.hostname = "@hostname"
myfirstconnection.username = "user"
myfirstconnection.password = "password"

queue.async(group: group) {
    myfirstconnection.connectToServer()
    print("1")
}
group.wait()

queue.async(group: group) {
    myfirstconnection.performCommand()
    print("2")
}
group.wait()

queue.async(group: group) {
    myfirstconnection.retrieveData()
    print("3")
}
group.wait()

queue.async(group: group) {
    myfirstconnection.endSession()
    print("4")
}
group.wait()

But, this does not seem to be working correctly because all the commands still run at the same time. Essentially I need each block above to run, then wait until completed before moving to the next block.

The NMSSH framework follows the (very!) common delegate pattern (eg, the UIText​Field​ view and its UIText​Field​Delegate protocol from UIKit framework; etc). As such, all network operations run in the background and, upon completion, fire a corresponding protocol methods.

You should implement the NMSSHSessionDelegate and NMSSHChannelDelegate protocols to be notified of such events. Keep in mind that your code structure will look very different when doing so.

Hope that helps ;-)

Ok , first of all using sleep() won't work at all, because how you want to estimate the time it takes to download something , some connections might be fast some might be slow. And from my understanding of your problem you want to execute some task and then do something with the data and then continue to the next task until they are done.One item at a time. For this situation I have a solution but I'm not sure if that's the best way to do it or not but it works.

        let serialQueue = DispatchQueue(label: "serialQueueWork" )
        let semaphore = DispatchSemaphore(value: 1)

        let task1 = DispatchWorkItem {
            semaphore.wait()
            print("1 started.")
            for _ in 0...5{
                print("♥️")
            }
        }

        let task2 = DispatchWorkItem  {
            semaphore.wait()
            print("2 started.")
            for _ in 0...5{
                print("♣️")
            }
        }

        task1.notify(queue: DispatchQueue.main) {
            print("1 is finished.")
            semaphore.signal()
        }

        task2.notify(queue: DispatchQueue.main) {
            print("2 is finished")
            semaphore.signal()
        }

        serialQueue.async(execute: task1 )
        serialQueue.async(execute: task2 )


// console result

1 started. ♥️ ♥️ ♥️ ♥️ ♥️ ♥️ 1 is finished. 2 started. ♣️ ♣️ ♣️ ♣️ ♣️ ♣️ 2 is finished

Using semaphore you take control of when the queue can continue to work. using DispatchWorkItem you get notified When the work is done and let the queue continue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM