using
Acota un recurso a una iteración: adquirido en el primer pull, liberado exactamente una vez — al completar o ante un error.
Lección
Archivos, sockets, cursores de base de datos — el valor que producen
es una secuencia, pero su vida útil es un paréntesis:
abrir, leer, cerrar, incluso cuando leer lanza una excepción.
Escribir ese paréntesis alrededor de un pipeline perezoso es
incómodo, porque «cuando termina la iteración» está allá donde esté
el consumidor. using(acquire, use, release) ata el
paréntesis a la iteración misma: acquire corre en el
primer pull (no al construir el pipeline — la pereza se preserva),
use(resource) aporta los elementos, y
release(resource) corre exactamente una vez, tras el
último elemento o justo antes de que un error se propague.
La forma async usingAsync permite que los tres pasos
sean asíncronos y compone con
concurrent — release sigue
disparándose exactamente una vez aunque haya pulls solapados en
vuelo. Si acquire falla, no hay nada que liberar, y el
error simplemente se propaga.
Una salvedad honesta, directa del modelo pull: un consumidor que
abandona la iteración — un break dentro de un
for-in, soltar el iterador — nunca llega al final, así
que release no puede ejecutarse. Acota la iteración con
take (un pipeline acotado
completa, y completar libera) o gestiona el recurso con
try/finally cuando la salida anticipada sea
el plan. Extensión de fxdart (sin contraparte en FxTS), inspirada en
el using de Rx.
Demo 1 · El paréntesis alrededor de una lectura perezosa
Demo 2 · Liberación ante error, exactamente una vez
Pruébalo tú
Ejercicio: dale una vida útil a la conexión.