Search code examples
c#unity-game-enginedotnetzip

DotNetZIp blocking unity


I'm using Ionic.Zip.dll to extract a zip file from unity.

It works well with zip.ExtractAll(zipPath, ExtractExistingFileAction.OverwriteSilently);

But while the archive is extracted the UI hangs (button effects, etc...). So I tried to use this inside a coroutine but got no result, I think it's the wrong way.

Have you already extracted something in this manner ?

EDIT :

I had problems tracking completion of the threaded function because of Unity restrictions. Finally done it with a bool and a coroutine :

   public bool extractionDone = false;
   IEnumerator CheckLauncherExtracted() {
       while(!extractionDone) yield return null;
       Debug.Log("ExtractionDone done !");
       OnLauncherFilesExtracted();
   }
    public void Extraction(){
        StartCoroutine("CheckLauncherExtracted");
        ThreadPool.QueueUserWorkItem(x => {
            FileManager.ExtractZipToDirectory(zipPath, zipExtractPath);
            extractionDone = true;
        });
    }

Solution

  • If zip.ExtractAll is blocking the main Thread or causing hiccups, use it in a new Thread or ThreadPool. Any of these should fix your problem. Coroutine won't help you in this case unless the zipping API you are using is specifically designed to work with Unity's coroutine.

    Fixing this with ThreadPool:

    void Start()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(ExtractFile));
    }
    
    private void ExtractFile(object a)
    {
        zip.ExtractAll(zipPath, ExtractExistingFileAction.OverwriteSilently);
    }
    

    Note that you can't call Unity's function from another Thread. For example, the ExtractFile function above is called in another Thread and you will get an exception if you attempt to use Unity API inside that function. See here for how to use Unity API in another Thread.