Home All Groups Group Topic Archive Search About

Thread.Join() in main thread makes UI unresponsive

Author
31 May 2006 11:39 AM
Markus Ewald
I created a simple splash screen with a progress bar in it that should
keep the user entertained while my application is busy loading resources.

The code goes like this:

     // Display the loading splash screen while we're busy.
     using(StartupForm loadingScreen = new StartupForm()) {
       loadingScreen.Show();

       loadResourcesThread.Start();
       loadResourcesThread.Join();

       loadingScreen.Close();
     }

What I expected was that the loading screen would still be kept
responsive (MSDN on Thread.Join(): "Blocks the calling thread until a
thread terminates, while continuing to perform standard COM and
SendMessage pumping"). What happens instead is that the splash screen
uses the hourglass cursor and doesn't redraw its controls while the main
thread sits in loadResourceThread.Join().

It works as expected if I use an ugly hack like this:

     loadResourcesThread.Start();
     while(loadResourcesThread.IsAlive)
       Application.DoEvents();
     loadResourcesThread.Join();

So is executing the message pump not enough to keep the UI in a .NET
application responsive?

Thanks ahead,
-Markus-

Author
31 May 2006 12:14 PM
Michael D. Ober
If the thread you are blocking with the Thread.Join() is the main
application thread, the message pump cannot be processed.  COM and
SendMessage are still working - it's simply that the receiving thread is
blocked.

Mike Ober.

Show quote
"Markus Ewald" <Markus_Ew***@gmx.net> wrote in message
news:uosmcbKhGHA.1264@TK2MSFTNGP05.phx.gbl...
> I created a simple splash screen with a progress bar in it that should
> keep the user entertained while my application is busy loading resources.
>
> The code goes like this:
>
>      // Display the loading splash screen while we're busy.
>      using(StartupForm loadingScreen = new StartupForm()) {
>        loadingScreen.Show();
>
>        loadResourcesThread.Start();
>        loadResourcesThread.Join();
>
>        loadingScreen.Close();
>      }
>
> What I expected was that the loading screen would still be kept
> responsive (MSDN on Thread.Join(): "Blocks the calling thread until a
> thread terminates, while continuing to perform standard COM and
> SendMessage pumping"). What happens instead is that the splash screen
> uses the hourglass cursor and doesn't redraw its controls while the main
> thread sits in loadResourceThread.Join().
>
> It works as expected if I use an ugly hack like this:
>
>      loadResourcesThread.Start();
>      while(loadResourcesThread.IsAlive)
>        Application.DoEvents();
>      loadResourcesThread.Join();
>
> So is executing the message pump not enough to keep the UI in a .NET
> application responsive?
>
> Thanks ahead,
> -Markus-
>
Author
5 Jun 2006 8:06 AM
Göran_Andersson
In addition: The non-hack solution is simply to add a sleep to the
waiting loop:

loadResourcesThread.Start();
while (loadResourcesThread.IsAlive) {
    Application.DoEvents();
    Thread.Sleep(100);
}
loadResourcesThread.Join();

This will keep the main thread from sitting on the edge of the chair
waiting intensely, and makes it lifts it's head a mere ten times a
second to see if something is happening.

Michael D. Ober wrote:
Show quote

> If the thread you are blocking with the Thread.Join() is the main
> application thread, the message pump cannot be processed.  COM and
> SendMessage are still working - it's simply that the receiving thread is
> blocked.
>
> Mike Ober.
>
> "Markus Ewald" <Markus_Ew***@gmx.net> wrote in message
> news:uosmcbKhGHA.1264@TK2MSFTNGP05.phx.gbl...
>> I created a simple splash screen with a progress bar in it that should
>> keep the user entertained while my application is busy loading resources.
>>
>> The code goes like this:
>>
>>      // Display the loading splash screen while we're busy.
>>      using(StartupForm loadingScreen = new StartupForm()) {
>>        loadingScreen.Show();
>>
>>        loadResourcesThread.Start();
>>        loadResourcesThread.Join();
>>
>>        loadingScreen.Close();
>>      }
>>
>> What I expected was that the loading screen would still be kept
>> responsive (MSDN on Thread.Join(): "Blocks the calling thread until a
>> thread terminates, while continuing to perform standard COM and
>> SendMessage pumping"). What happens instead is that the splash screen
>> uses the hourglass cursor and doesn't redraw its controls while the main
>> thread sits in loadResourceThread.Join().
>>
>> It works as expected if I use an ugly hack like this:
>>
>>      loadResourcesThread.Start();
>>      while(loadResourcesThread.IsAlive)
>>        Application.DoEvents();
>>      loadResourcesThread.Join();
>>
>> So is executing the message pump not enough to keep the UI in a .NET
>> application responsive?
>>
>> Thanks ahead,
>> -Markus-
>>
>
>
>

AddThis Social Bookmark Button