Avevo una coroutine in Unity3D che scaricava un zip da un server, lo estraeva nel percorso dati persistente e ne caricava il contenuto in memoria. Il flusso era simile al seguente:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
ExtractZip();
yield return StartCoroutine(LoadZipContent());
}
Ma il ExtractZip()
metodo (che utilizza la libreria DotNetZip) è sincrono, impiega troppo tempo e non mi lascia spazio per cedere durante il processo.
Ciò ha comportato la morte dell'applicazione (su dispositivi mobili) ogni volta che ho provato a estrarre un grande zip, che presumo sia dovuto al fatto che il thread principale non risponde troppo a lungo.
È noto che il sistema operativo mobile è noto (uccidere l'app se un frame impiega troppo tempo)?
Quindi, ho ipotizzato che l'estrazione della zip su un thread separato potesse risolvere il problema e sembra aver funzionato. Ho creato questa classe:
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;
}
E lo uso così:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
var extractAction = new ThreadedAction(ExtractZip);
yield return StartCoroutine(extractAction.WaitForComplete());
yield return StartCoroutine(LoadZipContent());
}
Ma non sono ancora sicuro se questo è il modo migliore per implementarlo, o se ho bisogno di bloccare _isDone
(non troppo abituato al multithreading).
Qualcosa può andare storto con questo / mi sto perdendo qualcosa?