Re: Populate an ImageList from another thread
- From: "Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx>
- Date: Sun, 16 Dec 2007 22:05:18 -0800
On Sun, 16 Dec 2007 17:20:27 -0800, Paul E Collins <find_my_real_address@xxxxxxx> wrote:
"Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx> wrote:
Mine works fine on my computer with or without the call to Sleep().
I am using Visual Studio 2005 version 8.0.50727.42 with Framework
2.0.50727 on Windows XP 5.1 Build 2600.xpsp_sp2_gdr.070227-2254 : SP2.
Here is a minimal code sample that locks up the UI with an hourglass
and no repainting. If I add a Thread.Sleep(1); in the loop then it
doesn't lock up at all. Is this to be expected? Doesn't it happen for
you?
I guess that depends on what the exact behavior you're seeing is. I suspect the behavior we're seeing is different, but I can see how different people might interpret the same behavior differently. So with that in mind...
First, there are some minor differences in our reported system configuration. I'm running VS 2005 Pro, .NET 2.0, XP SP2 which is all basically the same as you. However, my VS version number is actually 8.0.50727.762 (SP.050727-7600), and my OS version is "5.1 (Build 2600.xpsp_sp2_rtm.040803-2158 : Service Pack 2)" (in the System Configuration utility, it's listed as "5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)" (in the HAL section).
My PC is basically a Core 2 Duo, 2.33Ghz, 2GB of RAM. There's a twist though, as I'm running XP in a virtual machine, with 768MB of RAM. For most things though, since the VM is hardware-supported, performance is identical as compared to running without the VM.
I don't see why those minor differences would have such a significant effect, but given that there appears to be a difference, maybe they do.
Now, as for what happens when I run the code you posted: I do not find that the application locks up, nor do I get an hourglass cursor and no repainting.
You'll note that the code you posted endlessly creates new Bitmap instances and never releases them, so this obviously eventually results in an exception (oddly enough, instead of some sort of out-of-memory exception, I get an "invalid parameter" in the Bitmap constructor...just another GDI oddity I suppose, trying to tell me that if only I'd asked for a smaller Bitmap it would've worked :) ). That exception takes about five minutes to happen on my computer, after about 360000 iterations.
The other thing about the code is that it's in a fairly tight loop. But every time it calls Invoke() it yields to the main GUI thread. There's no way for it to starve the loop, but it does have the effect of slowing down the responsiveness for painting. The Invoke() itself, which requires two thread switches for each iteration of the loop, is certainly part of the performance overhead, but I believe the main issue is probably because the anonymous method instances pile up and eventually have to be garbage collected, so when the GC steps in everything else has to stop momentarily. This causes almost a 10X slowdown once the GC kicks in and starts having to do things regularly (see below for specifics).
So, the fact that this is happening does mean that repainting slows down. But at least on my computer, it doesn't stop altogether. The application remains responsive, though occasionally it lags as much as half a second to a second behind the user actions (dragging the window, obscuring it with another, etc.)
Because this is timing related, it's possible that if your hardware is significantly different from mine, that could explain a perceived difference in responsiveness. But beyond that, the code you posted should remain responsive on your computer, at least to some extent. If it literally locks up completely, and you are unable to note _any_ repainting or other UI response, that would be very odd.
IMHO, the next thing you should do is add a Debug.WriteLine() to the loop, with a counter printed as part of the debug output. That will help you differentiate between a true lock-up, in which case you'll only see the output once (assuming you put it before the call to Invoke()), and just some sort of sluggish behavior, in which case you'll see the counter iteratively being printed out.
If the former, then you definitely have some kind of weird problem with your installation; there's no reason that the code should deadlock, and it doesn't on my computer.
If the latter, well...the main problem you're apparently running into is trying to do too much given your configuration (whatever that is). I don't know how many Bitmaps you're trying to make and add to a list, but I suppose if it's enough of them you might have problems. But even in that case, you should see the program _eventually_ respond.
For what it's worth, on my PC, it can run though about 7000 iterations of the loop per second, at least initially (as the program continues, iterations take longer because of the memory consumption and garbage collection overhead, dropping to between 800 and 1000/sec).
Note that for any _reasonable_ number of Bitmaps (say, only a thousand or so), at least on my computer the operation completes so quickly that any interruption in responsiveness really isn't relevant. Depending on the speed of your computer, you may find things work out differently. You mentioned that batching up the Bitmaps helps performance, so perhaps that's the solution (assuming you're making a much larger number of them than I think is reasonable :) ). Most of the overhead in the loop is the invoking itself, so if you can vastly reduce the number of times you have to make that thread switch, you can greatly improve performance, returning responsiveness to the application.
Pete
.
- Follow-Ups:
- Re: Populate an ImageList from another thread
- From: Paul E Collins
- Re: Populate an ImageList from another thread
- References:
- Populate an ImageList from another thread
- From: Paul E Collins
- Re: Populate an ImageList from another thread
- From: Peter Duniho
- Re: Populate an ImageList from another thread
- From: Paul E Collins
- Re: Populate an ImageList from another thread
- From: Peter Duniho
- Re: Populate an ImageList from another thread
- From: Paul E Collins
- Populate an ImageList from another thread
- Prev by Date: BindingSource / DataSet / DataTable - Event when changed
- Next by Date: Re: Escape Sequences
- Previous by thread: Re: Populate an ImageList from another thread
- Next by thread: Re: Populate an ImageList from another thread
- Index(es):
Relevant Pages
|
Loading