Updating UI elements during long operations

Hey all,

I’m creating an app that connects to a hardware device (via a DLL in Windows). The connection operation can take a long time, up to a few seconds. What I am hoping to do is when the user presses a key, to update a UI Text element to say “Connecting…”, so that they know that their action is being processed while they wait for the device.

When a user presses a key:

  1. Change the Text to “Connecting…”.
  2. Call the DLL Connect method. I’ve also tried doing just a System.Threading.Thread.Sleep(1000).
  3. Change the Text to “Connected”.

Step 1 has no effect. There is just a long pause, then it says “Connected”. I understand that behavior if there was only one thread, but I had thought that the Renderer was on it’s own thread in the latest version of Unity? I was hoping the Renderer would update the screen while I was busy on the main thread. Can anyone explain what is happening?

Thanks!

I don’t know what your code looks like but it sounds like you are doing something like:

public void connect() {
    textObject.text = "Connecting...";
    connectToDLL();
}

You cannot block the main thread. The rendering MAY be on a separate thread but you are blocking the objects from updating what needs to be displayed. I’m not sure what you are trying to accomplish with sleeping the thread. The likely solution is to create a new thread and run it where connecToDLL() is.

Thanks for responding. :-]

I was using the Sleep() as a replacement to the DLL call to show that it had nothing to do with DLLs. I wouldn’t normally need to Sleep().

I do set the Text as your code shows above. I think I understand what you mean by saying that I’m blocking the objects from updating, so that must mean that objects are updated on the main thread. The problem I have with launching the call to the DLL on a separate thread is that it is unable to interact with the Unity API. That means I would have to manage my own event queue between threads (ie. to set Text to “Connected”)? I was hoping for something simpler.

Unfortunately threading may be the only way to keep the UI responsive. A hack that you may be able to get away with is starting a Coroutine, such as:

public void connect() {
   textObject.text = "Connecting...";
   StartCoroutine(dllConnect());
}

IEnumerator dllConnect() {
   yield return WaitForSeconds(1);

   connectToDLL(); \\The blocking DLL call
   textObject.text = "Connected";
}

I haven’t tested this but it should allow you to update the text and then block the main thread a second later until you are connected.

Good idea, thanks!