2017-03-27 218 views
1

我正在使用NMSSH來連接服務器,然後從該服務器獲取數據。但是,連接到服務器,執行命令和檢索數據都需要時間才能完成。之前,我使用sleep()命令來允許程序暫停並讓這些命令完成運行,但如果我沒有指定確切的睡眠時間,數據可能無法完全完成下載(因爲數據大小不同很難確定正確的睡眠量)。因此,在做了一些研究之後,調度組和異步操作似乎是正確的方法。我實現了這些如下:等待任務完成後再繼續下一個任務

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() 

但是,這似乎並沒有正常工作,因爲所有的命令仍然在同一時間運行。基本上我需要上面的每個塊運行,然後等待直到完成,然後再轉到下一個塊。

+0

爲什麼你需要發送四個異步請求開始?如果將這四個'myfirstconnection'調用包裝在一個異步模塊中,它們將相互依次執行 – NitroNbg

+0

因爲每次調用都需要一定的時間單獨運行,所以如果我一個接一個地調用它們,第一個調用將不會完成它試圖執行命令之前的連接,導致錯誤。 – SpartanEngr1297

回答

0

NMSSH框架如下(非常!)共同委託模式(例如,UIText​Field​視圖及其從UIKit框架UIText​Field​Delegate協議,等等)。因此,所有的網絡操作都在後臺運行,並且在完成後,啓動相應的協議方法。

您應該執行NMSSHSessionDelegateNMSSHChannelDelegate協議來通知此類事件。請記住,這樣做時你的代碼結構看起來會非常不同。

希望幫助;-)

+0

如果你指的是 ' - (void)channel:(NMSSHChannel *)channel didReadData:(NSString *)message'委託調用我之前使用過,但唯一的問題是它甚至可以識別輸入的執行命令(例如,cd home),我只希望在執行調用後返回的數據,所以我一直在''retrieveData'方法中使用'[self.session.channel lastResponse]'命令。 – SpartanEngr1297

+0

@ SpartanEngr1297這看起來像是API設計中的一個小問題。無論如何,如果你真的需要控制執行步驟 - 我想你會這樣做! - 你應該再次嘗試這些協議;-) –

0

好吧,首先使用sleep()不會在所有的工作,因爲你要如何估計需要下載東西的時候,一些連接可能是快一些可能慢。 從我對你的問題的理解中,你想要執行一些任務,然後對數據做一些事情,然後繼續下一個任務,直到完成。一次一個項目。 對於這種情況,我有一個解決方案,但我不知道這是否是最好的方法來做到這一點,但它的工作原理。

 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開始。 ♥️ ♥️ ♥️ ♥️ ♥️ ♥️ 1結束。 2開始。 ♣️ ♣️ ♣️ ♣️ ♣️ ♣️ 2結束

使用semaphore你拿的,當隊列可以繼續工作的控制。 使用DispatchWorkItem當工作完成並讓隊列繼續時,您會收到通知。