1

My application is multithreaded it has f.ex 25 active threads, and each thread pushes it status to list view item by delegate.

example:

    private delegate void SetBackColorDelegate(int index, Color color);
    private void SetBackColor(int index, Color color)
    {
        if (listView1.InvokeRequired)
        {
              listView1.Invoke(new SetBackColorDelegate(SetBackColor), new object[] { index, color });

        }
        else
        {
              listView1.Items[index].BackColor = color;
        }
    }

Depending on status it changes item color and etc. And it twinkles a lot, it looks very nasty :)

Maybe you can suggest how to avoid this ? How to speedup drawing ? Or maybe I should consider of start using some different component ?

Lukas Šalkauskas
  • 14,191
  • 20
  • 61
  • 77
  • I think you meant flickering. – Jean Azzopardi Jun 01 '09 at 10:31
  • Can you expand on the problem a bit? You have many threads changing the colour of the item, and the issue is that the colour changes a lot? Do you mean it flickers, like a double buffering issue or are your colour changes not performing fast enough and it is constantly behind, always changing colour as it tries to keep up? I don't understand why it is a problem that code requests to change the item's colour, and then the colour changes. – Martin Harris Jun 01 '09 at 11:03

2 Answers2

2

While I wait for your response to my comment. If the flickering is a double buffering issue then the accepted answer from this question will get you on your way. Set your listview to use the style from the answer and you're good to go. There is a performance penalty for this since it will ensure that the colour updates only happen in sync with the monitor's refresh rate (normally around 60 times per second), but it will stop the flicking/tearing that occurs when the updates fall between monitor refreshes.

Community
  • 1
  • 1
Martin Harris
  • 28,277
  • 7
  • 90
  • 101
1

Consider making each thread push its state to some shared data structure, and then poll that once per second from the UI thread using a timer. That way:

  • You don't have to worry about invoking from the non-UI threads
  • You won't get a "busy" UI
  • You'll still be reasonably up-to-date (vs an approach of saying "don't update if I've already updated recently)

I don't know much about UI timers in terms of efficiency - it's possible that such a timer would be relatively costly, so you may need to have some cross-thread communication anyway: make each non-UI thread enable the timer if it's not already enabled, and disable it when you do the update. That way you'll always be a second behind reality, but still with only one status update per second.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Yeah, It can be done easily. But I need instant status ;) that's the problem, I could do that each one sec, but I can't. – Lukas Šalkauskas Jun 01 '09 at 10:37
  • Then it sounds like you've got contradictory requirements: if you need to update something instantly, and you've got a lot of updates to display, then the screen will show all those updates, giving a flickering effect. – Jon Skeet Jun 01 '09 at 11:01
  • (If this is really just double buffering, then I misunderstood the problem - oops.) – Jon Skeet Jun 01 '09 at 12:24