En una entrevista técnica se presentó el escenario hipotético donde tendría crear una tarea asíncrona, y luego cancelarla. Luego se me preguntó: "¿Qué técnica de concurrencia usaría? (i.e. GCD, OperationQueue o Swift-Concurrency)?".
Respondí que mi respuesta dependía de las condiciones específicas de mi sistema. ¿Tengo permitido usar Swift-Concurrency? Si me es posible, elegiría esto, dada la facilidad de entender el método task.cancel(), junto con la validación de estado a través de isCancelled o checkCancellation().
Enseguida el entrevistador me dijo que no se me era permitido: Puedo usar GCD u OperationQueue.
Respondí que usaría GCD, crearía un DispatchWorkItem y luego lo cancelaría.
El entrevistador me dijo que un DispatchWorkItem no se podía cancelar y que por eso se usaba un OperationQueue cuando esta situación se podía presentar.
Pregunté si acaso DispatchWorkItem no funcionaba igual que un Task en el sentido que se podía cancelar y luego validar manualmente el estado (que sería invocar workItem.cancel() y validar con isCancelled) a lo que respondió que no era posible.
En realidad sí es posible, y se cancela de la misma forma que un Task: Para detener un DispatchWorkItem que ya haya iniciado, debo verificar internamente su estado de cancelación.
En Swift:
func testDispatchItems() {
let queue = DispatchQueue.global()
var item: DispatchWorkItem?
item = DispatchWorkItem { [weak self] in
for i in 0 ... 10_000_000 {
if item?.isCancelled ?? true { break }
print(i)
self?.heavyWork()
}
item = nil
}
queue.async(execute: item!)
queue.asyncAfter(deadline: .now() + 5) {
item?.cancel()
item = nil
}
}
En Objective-C se usaría dispatch_block_cancel para cancelar un bloque creado con dispatch_block_create, e internamente se tendría que validar su estado con dispatch_block_testcancel.
Top comments (0)