У меня была сопрограмма в Unity3D, которая загрузила zip-файл с сервера, извлекла его в постоянный путь данных и загрузила его содержимое в память. Поток выглядел примерно так:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
ExtractZip();
yield return StartCoroutine(LoadZipContent());
}
Но ExtractZip()
метод (который использует библиотеку DotNetZip), является синхронным, занимает слишком много времени и не оставляет мне места для отдачи во время процесса.
Это приводило к удалению приложения (на мобильных устройствах) всякий раз, когда я пытался извлечь большой zip-файл, что, как я полагаю, связано с тем, что основной поток слишком долго не отвечал.
Известно ли, что это то, что делает мобильная ОС (убить приложение, если кадр занимает слишком много времени)?
Итак, я предположил, что извлечение почтового индекса в отдельном потоке может решить проблему, и, похоже, это сработало. Я создал этот класс:
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;
}
И я использую это так:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
var extractAction = new ThreadedAction(ExtractZip);
yield return StartCoroutine(extractAction.WaitForComplete());
yield return StartCoroutine(LoadZipContent());
}
Но я до сих пор не уверен, является ли это лучшим способом реализовать его, или мне нужно блокировать _isDone
(не слишком привык к многопоточности).
Может ли что-то пойти не так с этим / я что-то упустил?
источник
Вам не нужно блокировать _isDone, но он должен быть помечен как volatile.
источник