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