title: Wait for thread to finish without blocking the UI thread
body: <p>I'm trying to create a message box class in unity and I want it to work the same way as the message box in windows forms which waits for a button to be pressed and than executes the code after that.</p>
  
  <pre><code>        var mbox = MessageBox.Show("Test", "test", MessageBoxButtons.YesNo);
          var test = mbox == DialogResult.Cancel; &lt;- it will wait here
  </code></pre>
  
  <p>I've tried to recreate that in 2 ways</p>
  
  <p><strong>Joining 2 threads</strong></p>
  
  <pre><code>    public void TestClick()
      {
          Thread thread1 = new Thread(TestMethod);
          thread1.Start();
          thread1.Join();
          Debug.Log("Done");
      }
  
      private void TestMethod()
      {
          float time = 0;
          while (time &lt;= 20)
          {
              Thread.Sleep(100);
              time++;
              Debug.Log("Im doing heavy work");
          }
      }
  </code></pre>
  
  <p>This one blocks the main thread and will resume only after <code>TestMethod</code> is completed but I don't want that because the user wont be able to interact with the message box during that time.</p>
  
  <p><strong>Asynchronous approach</strong> </p>
  
  <pre><code>    public delegate int AsyncTask();
  
      public void TestClick()
      {
          RunAsyncAndWait();
          Debug.Log("Done");
      }
  
      public int Method1()
      {
          float time = 0;
          while (time &lt;= 20)
          {
              Thread.Sleep(100);
              time++;
              Debug.Log("Im doing heavy work");
          }
          return 0;
      }
  
  
      public void RunAsyncAndWait()
      {
          AsyncTask ac1 = Method1;
  
          WaitHandle[] waits = new WaitHandle[1];
          IAsyncResult r1 = ac1.BeginInvoke(null, null);
          waits[0] = r1.AsyncWaitHandle;
  
          WaitHandle.WaitAll(waits);
  
      }
  </code></pre>
  
  <p>This works exactly like the first one but it behaves weirdly if we change some stuff like the size of the <code>WaitHandle[]</code> to <code>WaitHandle[] waits = new WaitHandle[2];</code>.</p>
  
  <p>Now this works more like what I need as it continuously writes stuff in the Console rather than just posting 21 messages at once like the previous methods but the moment it runs it pauses the unity scene (I can manually resume it and the program will run just fine) and it keeps on printing stuff in the console and I get this error  </p>
  
  <blockquote>
    <p>ArgumentNullException: null handle
    Parameter name: waitHandles
    System.Threading.WaitHandle.CheckArray (System.Threading.WaitHandle[] handles, Boolean waitAll) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Threading/WaitHandle.cs:77)
    System.Threading.WaitHandle.WaitAll (System.Threading.WaitHandle[] waitHandles) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Threading/WaitHandle.cs:109)
    Assets.Scripts.Test.RunAsyncAndWait () (at Assets/Scripts/Test.cs:40)
    Assets.Scripts.Test.TestClick () (at Assets/Scripts/Test.cs:16)
    UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:153)
    UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:630)
    UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:765)
    UnityEngine.Events.UnityEvent.Invoke () (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53)
    UnityEngine.UI.Button.Press () (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35)
    UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44)
    UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52)
    UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
    UnityEngine.EventSystems.EventSystem:Update()</p>
  </blockquote>
  
  <p>The first line sounded to me like I might need a callback function here so I quickly added something just to test it out</p>
  
  <pre><code>IAsyncResult r1 = ac1.BeginInvoke(ar =&gt; Debug.Log("Done"), null);
  </code></pre>
  
  <p>But with no luck nothing changed. </p>
  
  <p>Any tips how can I approach this problem as a whole (making a message box, blocking the thread until a button is pressed), or maybe some more info on how Microsoft has implemented that in windows forms ?</p>