thread gcd example dispatchqueue dispatch_async async grand-central-dispatch swift3

grand central dispatch - example - ¿Cómo detener un DispatchWorkItem en GCD?



operation queue swift 4 (2)

GCD no realiza cancelaciones preventivas. Por lo tanto, para detener un elemento de trabajo que ya ha comenzado, debe probar las cancelaciones usted mismo. En Swift, cancel el DispatchWorkItem . En Objective-C, llame a dispatch_block_cancel en el bloque que creó con dispatch_block_create . Luego puede probar para ver si se canceló o no con isCancelled en Swift (conocido como dispatch_block_testcancel en Objective-C).

func testDispatchItems() { let queue = DispatchQueue.global() var item: DispatchWorkItem! // create work item item = DispatchWorkItem { [weak self] in for i in 0 ... 10_000_000 { if item.isCancelled { break } print(i) self?.heavyWork() } item = nil // resolve strong reference cycle } // start it queue.async(execute: item) // after five seconds, stop it if it hasn''t already queue.asyncAfter(deadline: .now() + 5) { [weak item] in item?.cancel() } }

O, en Objective-C:

- (void)testDispatchItem { dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0); static dispatch_block_t block = nil; // either static or property __weak typeof(self) weakSelf = self; block = dispatch_block_create(0, ^{ for (long i = 0; i < 10000000; i++) { if (dispatch_block_testcancel(block)) { break; } NSLog(@"%ld", i); [weakSelf heavyWork]; } block = nil; }); // start it dispatch_async(queue, block); // after five seconds, stop it if it hasn''t already dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if (block) { dispatch_block_cancel(block); } }); }

Actualmente estoy jugando con Grand Central Dispatch y descubrí una clase llamada DispatchWorkItem . La documentación parece un poco incompleta, así que no estoy seguro de usarla de la manera correcta. Creé el siguiente fragmento y esperaba algo diferente. Esperaba que el artículo se cancelara después de llamar a cancel en él. Pero la iteración continúa por alguna razón. ¿Alguna idea de lo que estoy haciendo mal? El código me parece bien.

@IBAction func testDispatchItems() { let queue = DispatchQueue.global(attributes:.qosUserInitiated) let item = DispatchWorkItem { [weak self] in for i in 0...10000000 { print(i) self?.heavyWork() } } queue.async(execute: item) queue.after(walltime: .now() + 2) { item.cancel() } }


No hay una API asincrónica en la que llamar a un método "Cancelar" cancele una operación en ejecución. En cada caso, un método de "Cancelar" hará algo para que la operación pueda averiguar si está cancelado, y la operación debe verificar esto de vez en cuando y luego dejar de hacer más trabajo por sí mismo.

No conozco la API en cuestión, pero normalmente sería algo así como

for i in 0...10000000 { if (self?.cancelled) break; print(i) self?.heavyWork() }