J'ai eu une coroutine dans Unity3D qui a téléchargé un zip à partir d'un serveur, l'a extrait dans le chemin de données persistant et a chargé son contenu en mémoire. Le flux ressemblait à ceci:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
ExtractZip();
yield return StartCoroutine(LoadZipContent());
}
Mais la ExtractZip()
méthode (qui utilise la bibliothèque DotNetZip), est synchrone, prend trop de temps et ne me laisse aucune place pour céder pendant le processus.
Cela a entraîné la suppression de l'application (sur les appareils mobiles) chaque fois que j'essayais d'extraire un gros zip, ce qui, je suppose, est dû au fait que le thread principal ne répond plus trop longtemps.
Est-ce quelque chose que le système d'exploitation mobile est connu pour faire (tuer l'application si un cadre prend trop de temps)?
J'ai donc supposé que l'extraction du zip sur un thread séparé pourrait résoudre le problème, et cela semble avoir fonctionné. J'ai créé cette 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;
}
Et je l'utilise comme ceci:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
var extractAction = new ThreadedAction(ExtractZip);
yield return StartCoroutine(extractAction.WaitForComplete());
yield return StartCoroutine(LoadZipContent());
}
Mais je ne sais toujours pas si c'est la meilleure façon de l'implémenter, ou si j'ai besoin de verrouiller _isDone
(pas trop habitué au multithreading).
Est-ce que quelque chose peut mal tourner / est-ce que je manque quelque chose?
la source
Vous n'avez pas besoin de verrouiller _isDone, mais il doit être marqué comme volatile.
la source