Ich hatte eine Coroutine in Unity3D, die eine Zip-Datei von einem Server heruntergeladen, in den persistenten Datenpfad extrahiert und deren Inhalt in den Speicher geladen hat. Der Fluss sah ungefähr so aus:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
ExtractZip();
yield return StartCoroutine(LoadZipContent());
}
Aber die ExtractZip()
Methode (die die DotNetZip-Bibliothek verwendet) ist synchron, dauert zu lange und lässt mir während des Prozesses keinen Platz zum Nachgeben.
Dies führte dazu, dass die Anwendung (auf Mobilgeräten) beendet wurde, wenn ich versuchte, eine große Zip-Datei zu extrahieren. Ich gehe davon aus, dass der Haupt-Thread zu lange nicht mehr reagiert.
Ist dies etwas, von dem bekannt ist, dass es ein mobiles Betriebssystem tut (beenden Sie die App, wenn ein Frame zu lange dauert)?
Also nahm ich an, dass das Extrahieren der Zip-Datei in einem separaten Thread das Problem lösen könnte, und es scheint funktioniert zu haben. Ich habe diese Klasse erstellt:
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;
}
Und ich benutze es so:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
var extractAction = new ThreadedAction(ExtractZip);
yield return StartCoroutine(extractAction.WaitForComplete());
yield return StartCoroutine(LoadZipContent());
}
Aber ich bin mir immer noch nicht sicher, ob dies der beste Weg ist, es zu implementieren, oder ob ich sperren muss _isDone
(nicht zu sehr an Multithreading gewöhnt).
Kann damit etwas schief gehen / fehlt mir etwas?
quelle
Sie müssen _isDone nicht sperren, aber es muss als flüchtig markiert werden.
quelle