Tuve una rutina en Unity3D que descargó un zip de un servidor, lo extrajo a la ruta de datos persistente y cargó su contenido en la memoria. El flujo se parecía a esto:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
ExtractZip();
yield return StartCoroutine(LoadZipContent());
}
Pero el ExtractZip()
método (que usa la biblioteca DotNetZip), es sincrónico, toma demasiado tiempo y no me deja ningún lugar para ceder durante el proceso.
Esto resultó en la eliminación de la aplicación (en dispositivos móviles) cada vez que intentaba extraer un zip grande, lo que supongo se debe a que el hilo principal no responde durante demasiado tiempo.
¿Es esto algo que se sabe que hace el sistema operativo móvil (matar la aplicación si un marco tarda demasiado)?
Entonces, asumí que extraer el zip en un hilo separado podría resolver el problema, y parece haber funcionado. Creé esta clase:
public class ThreadedAction
{
public ThreadedAction(Action action)
{
var thread = new Thread(() => {
if(action != null)
action();
_isDone = true;
});
thread.Start();
}
public IEnumerator WaitForComplete()
{
while (!_isDone)
yield return null;
}
private bool _isDone = false;
}
Y lo uso así:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
var extractAction = new ThreadedAction(ExtractZip);
yield return StartCoroutine(extractAction.WaitForComplete());
yield return StartCoroutine(LoadZipContent());
}
Pero todavía no estoy seguro de si esta es la mejor manera de implementarlo, o si necesito bloquear _isDone
(no demasiado acostumbrado a subprocesos múltiples).
¿Algo puede salir mal con esto / me estoy perdiendo algo?
fuente
No necesita bloquear _isDone, pero sí debe estar marcado como volátil.
fuente