2017-04-07 6 views
0

Wie kann verhindert werden, dass wiederholt auf einen Codeblock von demselben Thread zugegriffen wird?Synchronisierung mehrerer Tasks auf einem einzelnen Thread

Angenommen, ich habe den nächsten Code:

func sendAnalytics() { 
    // some synchronous work 

    asyncTask() { _ in 
     completion() 
    } 
} 

Ich mag jeden Thread aus dem Zugriff auf "// einige synchrone Arbeit", zu verhindern, vor der Fertigstellung genannt wurde.

scheinen nur den Zugriff auf diesen Code aus mehreren Threads zu verhindern und speichern Sie mich nicht vom Zugriff auf diesen Code aus dem einzelnen Thread. Gibt es eine Möglichkeit, dies richtig zu tun, ohne benutzerdefinierte Lösungen zu verwenden?

Mein wiederholt Zugriff, ich meine, diese sendAnalytics aus einem Thread mehrmals aufrufen. Nehmen wir an, ich habe eine für, wie folgt aus:

for i in 0...10 { 
    sendAnalytics() 
} 

Jeder nächste Anruf wird nicht für die Fertigstellung warten innerhalb sendAnalytics aufgerufen (offensichtlich). Gibt es eine Möglichkeit, die nächsten Anrufe warten zu lassen, bevor der Abschluss ausgelöst wird? Oder die ganze Art zu denken ist falsch und ich muss dieses Problem höher lösen, am Körper?

+0

Es hängt davon ab, ob der zweite Anrufer blockieren möchten, bis die erste der zweite Anruf – Paulw11

+0

die überspringen oder einfach beendet hat blockieren zweiter Anrufer –

+0

Dann verwenden Sie einen Dispatch_semaphore mit einer anfänglichen Zählung von 0. Vorsicht, die Hauptwarteschlange jedoch blockiert – Paulw11

Antwort

2

Sie können eine DispatchSemaphore verwenden, um sicherzustellen, dass ein Aufruf abgeschlossen ist, bevor der nächste

let semaphore = DispatchSemaphore(value:1) 

func sendAnalytics() { 
    self.semaphore.wait() 
    // some synchronous work 

    asyncTask() { _ in 
     completion() 
     self.semaphore.signal() 
    } 
} 

Der zweite Aufruf von sendAnalytics blockiert, bis der erste AsyncTask abgeschlossen ist starten. Sie sollten darauf achten, die Hauptwarteschlange nicht zu blockieren, da Ihre App dadurch nicht mehr reagiert. Es ist wahrscheinlich sicherer, die sendAnalytics Anruf auf seine eigene Serien Absende-Warteschlange zu versenden, dieses Risiko zu beseitigen:

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

func sendAnalytics() { 
    analyticsQueue.async { 
     self.semaphore.wait() 
     // some synchronous work 

     asyncTask() { _ in 
      completion() 
      self.semaphore.signal() 
     } 
    } 
} 
+0

es ruft überhaupt nicht, für mich. aber es funktioniert für Let Semaphore = DispatchSemaphore (Wert: 1) –

+0

Sorry, mein Fehler. 1 ist richtig – Paulw11

Verwandte Themen