खोज…


परिचय

संबंधित विषय:

ग्रैंड सेंट्रल डिस्पैच

संगामिति

परिचय

मान लीजिए कि आपके पास कई थ्रेड चल रहे हैं। प्रत्येक धागा एक कार्य कर रहा है। जब आप सभी कार्य-सूत्र पूरे हो जाते हैं, तो आप या तो मेनहार्ड या किसी अन्य थ्रेड पर सूचित करना चाहते हैं।

ऐसी समस्या का सबसे सरल समाधान एक DispatchGroup

DispatchGroup का उपयोग करते समय, प्रत्येक अनुरोध के लिए, आप समूह में enter करते हैं और प्रत्येक पूर्ण अनुरोध के लिए, आप समूह को leave

जब समूह में अब अनुरोध नहीं होते हैं, तो आपको notify किया जाएगा (अधिसूचित)।


उपयोग:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        let dispatchGroup = DispatchGroup() //Create a group for the tasks.
        let session: URLSession = URLSession.shared
        
        dispatchGroup.enter() //Enter the group for the first task.
        
        let firstTask = session.dataTask(with: URLRequest(url: URL(string: "https://stackoverflow.com")!)) { (data, response, error) in
            
            //Process Response..
            
            dispatchGroup.leave() //Leave the group for the first task.
        }

        
        dispatchGroup.enter()  //Enter the group for the second task.
        
        let secondTask = session.dataTask(with: URLRequest(url: URL(string: "https://google.ca")!)) { (data, response, error) in
            
            //Process Response..
            
            dispatchGroup.leave()  //Leave the group for the second task.
        }
        
        
        //Get notified on the main thread/queue.. when ALL of the tasks above has been completed.
        dispatchGroup.notify(queue: DispatchQueue.main) { 
            
            print("Every task is complete")
            
        }
        
        
        //Start the tasks.
        firstTask.resume()
        secondTask.resume()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

उपरोक्त के साथ, आपको सभी कार्यों के पूरा होने तक असीम wait करने की आवश्यकता नहीं है। आप एक लोडर को प्रदर्शित कर सकते हैं इससे पहले कि सभी कार्य शुरू हो गए हैं और सभी कार्यों को पूरा करने के बाद लोडर को खारिज कर दें। इस तरह, आपका मुख्य धागा अवरुद्ध नहीं होता है और आपका कोड साफ रहता है।

अब मान लें कि आप भी चाहते थे कि कार्यों को ordered या क्रमबद्ध तरीके से उनकी प्रतिक्रियाओं को जोड़ा जाए। आप निम्नलिखित कर सकते हैं:

import UIKit

//Locking mechanism..
func synchronized(_ lock: AnyObject, closure: () -> Void) {
    objc_sync_enter(lock)
    closure()
    objc_sync_exit(lock)
}

class ViewController: UIViewController {

    let lock = NSObject() //Object to lock on.
    var responseArray = Array<Data?>() //Array of responses.
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let dispatchGroup = DispatchGroup()
        let session: URLSession = URLSession.shared
        
        dispatchGroup.enter() //Enter the group for the first task.
        
        let firstTask = session.dataTask(with: URLRequest(url: URL(string: "https://stackoverflow.com")!)) { (data, response, error) in
            
            //Process Response..

            synchronized(self.lock, closure: { () -> Void in
                self.responseArray[0] = data ?? nil
            })

            dispatchGroup.leave() //Leave the group for the first task.
        }

        
        dispatchGroup.enter()  //Enter the group for the second task.
        
        let secondTask = session.dataTask(with: URLRequest(url: URL(string: "https://google.ca")!)) { (data, response, error) in
            
            //Process Response..
            
            synchronized(self.lock, closure: { () -> Void in
                self.responseArray[1] = data ?? nil
            })
            
            dispatchGroup.leave()  //Leave the group for the second task.
        }
        
        
        //Get notified on the main thread.. when ALL of the requests above has been completed.
        dispatchGroup.notify(queue: DispatchQueue.main) { 
            
            print("Every task is complete..")
            
            for i in 0..<self.responseArray.count {
                
                if self.responseArray[i] == nil {
                    print("Request #\(i) Failed.\n")
                }
                else {
                    print("Request #\(i) Succeeded.\n")
                }
            }
        }
        
        //Two tasks added to the array. Responses are assumed nil until they complete.
        self.responseArray.append(nil)
        self.responseArray.append(nil)
        
        //Start the tasks.
        firstTask.resume()
        secondTask.resume()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

टिप्पणियाँ

प्रत्येक प्रविष्टि एक में एक निकास होना आवश्यक है DispatchGroup । यदि आप entering बाद leave भूल जाते हैं, तो आप खुद को स्थापित कर रहे हैं। कार्य पूर्ण होने पर आपको सूचित नहीं किया जाएगा।

enter की राशि leave की राशि के बराबर होनी चाहिए।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow