簡體   English   中英

DispatchGroup.wait 不等待

[英]DispatchGroup.wait not waiting

我在理解或使用 Dispatchgroup 時遇到問題。 我已經閱讀了很多關於它們的內容,但是大多數示例/文檔都非常模糊或與我想要做的不一樣,但是每次我提到我的問題時,每個人都會說“使用調度組!”。

這是我想要做的(注意:順序是至關重要的):

  • 發送藍牙寫入特性。
  • 設備接收值,並吐出一些東西作為響應
  • 讀取藍牙響應(通過讀取特性)
  • 發送新的寫入特性(不同的命令)
  • 設備收到 NEW 命令,吐出 NEW 數據響應

重復兩次(總共 3 個命令,總共 3 個不同的響應)。


我的代碼:

func tPodInitialSetUp()
    {
        print ("* * * * * BEGIN SET-UP * * * * *")
        let setupDispatchGroup = DispatchGroup()

        setupDispatchGroup.enter()
        self.writeValue(command: Data(CommandModeCmd)) //231: Put t-Pod in command mode, burst mode is OFF returns OK
        setupDispatchGroup.leave()

        setupDispatchGroup.wait()

        setupDispatchGroup.enter()
        deviceConnected?.readValue(for: deviceConnectedCh1n2Char!)
        print("Sent command 231: returned: \(receivedString1)")
        if receivedString1.lowercased() == "ok"
        {
            print("t-Pod burst mode is OFF")
        }
        setupDispatchGroup.leave()

        setupDispatchGroup.wait()

        setupDispatchGroup.enter()
        self.writeValue(command: Data(loadProbeCalCmd)) //202: load calibration constants of probe, returns ok or 0
        setupDispatchGroup.leave()

        setupDispatchGroup.wait()

        setupDispatchGroup.enter()
        deviceConnected?.readValue(for: deviceConnectedCh1n2Char!)
        print("Sent command 202: returned: \(receivedString1)")
        if receivedString1.lowercased() == "ok"
        {
            print("Probe Constants loaded")
        }
        if receivedString1 == "0"
        {
            print("No probe connected")
        }
        setupDispatchGroup.leave()

        setupDispatchGroup.wait()

        setupDispatchGroup.enter()
        self.writeValue(command: Data(probeSNCmd)) //205: load probe serial number
        setupDispatchGroup.leave()

        setupDispatchGroup.wait()

        setupDispatchGroup.enter()
        deviceConnected?.readValue(for: deviceConnectedCh1n2Char!)
        print("Sent command 205: returned: \(receivedString1)")
        if (receivedString1.count == 6)
        {
            print("received Probe SN: \(receivedString1)")
            probeSN = receivedString1
        }
        setupDispatchGroup.leave()

        setupDispatchGroup.notify(queue: .main)
        {
            tPodSN = String(describing: connectedDeviceName!.dropFirst(7))
            print ("* * * SET-UP COMPLETE * * *")
            self.writeValue(command: Data(resetCmd)) //200: resets t-Pod
            self.writeValue(command: Data(beaconOffCmd)) //211: turns beacon off (temperature output)
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
        {
            self.dataDisplaySubView.isHidden = false
            print ("Adding observers!")

            NotificationCenter.default.addObserver(self, selector: #selector(self.updateIncomingData), name: NSNotification.Name(rawValue: DATA_PARSED), object: nil) //Run every time you receive data from BLE

            NotificationCenter.default.addObserver(self, selector: #selector(self.calculateTNU), name: NSNotification.Name(rawValue: TOGGLESWITCH_TOGGLED), object: nil) //Run in case the toggle switches change and data needs to be re-calculated

            NotificationCenter.default.addObserver(self, selector: #selector(self.parseReceivedData), name: NSNotification.Name(rawValue: DEVICE_FINISHED_SENT_DATA), object: nil) //Run every time you receive the notification that the whole data has been sent
        }
    }

這將調用具有以下代碼和確認的藍牙寫入命令:

func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
        guard error == nil else {
            print("Error writing descriptor: " + (error?.localizedDescription)!)
            return
        }
        print("Descriptor Value sent")
    }

現在,這是我的輸出:

* * * * * BEGIN SET-UP * * * * *
***** WRITING *****
Wrote: 1 bytes
***** WRITING *****
Wrote: 1 bytes
Sent command 231: returned: **T-Pod-9Ch**
***** WRITING *****
Wrote: 1 bytes
Sent command 202: returned: **T-Pod-9Ch**
***** WRITING *****
Wrote: 1 bytes
Sent command 205: returned: **T-Pod-9Ch**
* * * SET-UP COMPLETE * * *
***** WRITING *****
Wrote: 1 bytes
***** WRITING *****
Wrote: 1 bytes
Characteristic Value sent
Adding observers!
Characteristic Value sent
Characteristic Value sent
Characteristic Value sent
Characteristic Value sent
Clearing TNU Array

現在,正如您所看到的,“發送的特征值”是藍牙函數在發送值時給出的確認,但是這個輸出是在運行完整個代碼后創建的,所以基本上它把命令放在某個管道中,忘記了它們做了所有其他的事情,然后發送了命令,因此我正在閱讀的回復都是無稽之談! 正如您所看到的,所有接收到的字符串都是T-Pod-9Ch (這只是它的正常突發輸出),我應該從命令中得到的預期響應是 OK、OK 和 6 位數字(按此順序)。
請幫忙,我已經閱讀了很多次關於調度組應該如何工作的內容,但我就是無法讓他們做我想做的事。

如果我問對了你的問題,你需要在發送新命令之前等待答案。

但是您的寫入沒有完成塊,這就是為什么在您的情況下使用 dispatchGroup 沒有意義。

下面的代碼是使用調度組的常見示例

func someMethod(completionHandler: @escaping ()-> Void) {


 //we need to get or set some data in separated queue
    DispatchQueue.global(qos: .background).async {

    let group = DispatchGroup()

    //let's say we have an array of urls and we need to load images and put them to an array
    for url in someUrlArray {
          group.enter()
          SomeLoaderClass.load(url) { image in
                //add received image

                //leave the group
               group.leave() 
           }
    }

    //now we need to wait until all images will be downloaded 
    group.wait()

    //then we can finish and call the completion in the main queue
    DispatchQueue.main.async {
         completionHandler()
    }
   }
}

在您的情況下,您可能有多種選擇:

首先,如果您知道如果您發送一個命令並收到該命令的正確答案,您可以按以下順序調用方法:

  1. 調用一種方法發送命令 1

  2. 在收到命令 1 的應答后調用另一種方法

  3. 調用另一種方法來發送命令 2

  4. 在獲得命令 2 的答案后,還有一種方法......

n. 完成設置

就像我需要注冊一個用戶一樣,我需要先發送定義的憑據,從服務器獲取令牌,然后在它之后運行一些東西。

所以你必須為每個命令添加一個額外的方法,你將根據順序調用它們

如果您無法識別將要獲得響應的命令,並且您確定只發送了一個命令並且只等待了一個響應,那么您可以按照以下描述的方式使用 dispatch group:

typealias Callback = ()->Void
class SomeManagerClass {
       var callback: Callback?

       func initiateSetup(){
              DispatchQueue.global(qos: .background).async { [weak self] in
                    let group = DispatchGroup()
                   //now we can send commands
                   group.enter()
                   self?.sendCommand(SomeDataForTheFirstCommand) {
                          //when the first answer will be received, it will init the callback, so you can leave the group now
                         group.leave()
                    }
                   //sending the second command
                    group.enter()
                   self?.sendCommand(SomeDataForTheSecondCommand) {
                          //waiting for the second answer will be received
                         group.leave()
                    }

                    //.... more commands sending same way
                    group.wait()
                    //now all commands was send and you got an answer for each

                    //finishing setup 
                         DispatchQueue.main.async{
                        self?.finishSetup()
                   }
              }
       }

      func sendCommand(_ command: Data, callback: Callback?){
             self.writeValue(command: command)
             self.callback = callback 
      }

      func answerReceived(){
             //this is just an example method that is called when you get an answer for any command
            //now we can callback 
            self.callback?()
      }

      func finishSetup(){

           //do something 
      }
}

如果您需要更多詳細信息,請告訴我

使用 Dispatch 組的示例

private func performTask1() -> String {
    print("Task1")
    var result: String?
    let background = DispatchQueue.global(qos: .background)

    let dispatchGroup = DispatchGroup()

    dispatchGroup.enter()
    background.asyncAfter(deadline: .now() + 3) {
        result = "Task1 is performed"
         dispatchGroup.leave()
    }
   dispatchGroup.wait()
    return result!
}

試試這個來理解 DispactGroup 的概念!

試試吧!

leave()所需的DispatchQueue.global(qos: .background )

func dispatchGroup() -> String {

   var message = ""

   let group = DispatchGroup()

   group.enter()

   DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 5) {
        message = "Hiii Friends"
        group.leave()
   }

   group.wait()

   return message
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM