2009-06-01 5 views
1

Мое приложение имеет многопоточность, у него есть f.ex 25 активных потоков, и каждый поток передает его статус в элемент списка списка делегатом.ListView - как избежать мерцания (.NET/C#)?

пример:

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; 
     } 
    } 

В зависимости от статуса меняет цвет элемента и т.д. И это мерцает много, это выглядит очень противный :)

Может быть, вы можете предложить, как избежать этого? Как ускорить рисование? Или, может быть, я должен подумать о начале использования какого-то другого компонента?

+0

Я думаю, что вы имели в виду мерцание. –

+0

Можете ли вы немного расширить проблему? У вас много потоков, изменяющих цвет элемента, и проблема в том, что цвет сильно меняется? Вы имеете в виду, что это мерцает, как проблема с двойной буферизацией или ваши изменения цвета не работают достаточно быстро, и она постоянно позади, всегда меняя цвет, когда он пытается идти в ногу с собой? Я не понимаю, почему это проблема, когда код запрашивает изменение цвета элемента, а затем цвет меняется. –

ответ

2

Пока я жду ответа на свой комментарий. Если мерцание равно, проблема с двойной буферизацией, тогда принятый ответ от this question доставит вас на ваш путь. Установите свой список, чтобы использовать стиль из ответа, и вам хорошо идти. Для этого существует штраф за производительность, так как он гарантирует, что обновления цвета будут синхронизироваться только с частотой обновления монитора (обычно около 60 раз в секунду), но это остановит щелчок/разрывы, возникающие, когда обновления падают между обновлениями монитора ,

+0

Спасибо :) actualy this http://stackoverflow.com/questions/76993/how-to-double-buffer-net-controls-on -a-form помог мне :) –

1

Подумайте о том, чтобы каждый поток нажимал свое состояние на какую-то общую структуру данных, а затем опросил один раз в секунду из потока пользовательского интерфейса, используя таймер. Таким образом:

  • Вам не придется беспокоиться о вызове из нитей без UI
  • Вы не получите «занято» UI
  • Вы все еще будете разумно вверх-to date (против подхода «не обновлять, если я уже недавно обновлялся»)

Я мало знаю о таймерах пользовательского интерфейса с точки зрения эффективности - возможно, такой таймер будет относительно дорогостоящим , так что вы, , могут, так или иначе, должны иметь какое-то поперечное сообщение: сделать каждый не-UI t hread включить таймер, если он еще не включен, и отключить его при обновлении. Таким образом, вы всегда будете вторым за реальностью, но все равно с одним обновлением статуса в секунду.

+0

Да, это можно сделать легко. Но мне нужен мгновенный статус;) вот в чем проблема, я могу сделать это каждую секунду, но не могу. –

+0

Тогда, похоже, у вас есть противоречивые требования: если вам нужно что-то обновить мгновенно, и у вас есть много обновлений для отображения, тогда на экране будут показаны все эти обновления, дающие мерцающий эффект. –

+0

(Если это действительно просто двойная буферизация, то я неправильно понял проблему - oops.) –