I had a coroutine in Unity3D that downloaded a zip from a server, extracted it to the persistent data path, and loaded its contents into memory. The flow looked something like this:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
ExtractZip();
yield return StartCoroutine(LoadZipContent());
}
But the ExtractZip()
method (which uses the DotNetZip library), is synchronous, takes too long, and leaves me no place to yield during the process.
This resulted in the application being killed (on mobile devices) whenever I tried to extract a large zip, which I assume is due to the main thread becoming unresponsive for too long.
Is this something that mobile OS are known to do (kill the app if a frame takes too long)?
So, I assumed that extracting the zip on a separate thread might solve the problem, and it seems to have worked. I created this class:
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;
}
And I use it like this:
IEnumerator LongCoroutine()
{
yield return StartCoroutine(DownloadZip());
var extractAction = new ThreadedAction(ExtractZip);
yield return StartCoroutine(extractAction.WaitForComplete());
yield return StartCoroutine(LoadZipContent());
}
But I'm still not sure if this is the best way to implement it, or if I need to lock _isDone
(not too used to multithreading).
Can something go wrong with this / am I missing something?