C # Background Worker UI Обновление - PullRequest
5 голосов
/ 04 августа 2010

Я пытаюсь использовать фонового работника для извлечения большого объема данных из базы данных без остановки основного потока.Это, кажется, работает хорошо, за исключением того, что когда дело доходит до обновления пользовательского интерфейса, обновление останавливает экран.Соответствующий код выглядит следующим образом:

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {               
        lvwTest.BeginUpdate();
        lvwTest.Items.Clear();

        // Populate the UI
        foreach (TestItem ti in testData)
        {
            ListViewItem lvi = lvwTest.Items.Add(ti.Value1);
            lvi.SubItems.Add(ti.Value2);
        }

        lvwTest.EndUpdate();                     
    }

Обновление занимает около 2–3 секунд, на это время экран блокируется.Я понимаю, что только основной поток может обновлять экран, но возможно ли каким-то образом загрузить эти данные в память (в фоновом потоке или другом экземпляре списка или чего-то еще), а затем просто отобразить его?Все, чего я хочу, это чтобы программа просто обновляла данные, не занимая время в главном потоке.

Ответы [ 4 ]

1 голос
/ 04 августа 2010

Я рекомендую загрузить данные в память и использовать виртуальный режим ListView. Таким образом, вы создаете ListViewItem объекты только по мере необходимости.

1 голос
/ 04 августа 2010

Если вам нужно загрузить действительно большой объем данных в интерфейс, это потребует времени и заблокирует наше приложение. Опция умной прокрутки или нумерации страниц. Вы загружаете все данные, но кладете их по частям по запросу пользователя.

0 голосов
/ 04 августа 2010

Поскольку большинство из вышеперечисленных являются хорошими советами, но на самом деле не решают вашу непосредственную проблему, вот другой подход: это обновит ваш графический интерфейс и сохранит его отзывчивость.Предполагая, что вы находитесь в WinForm App?

        Application.DoEvents();
        this.Refresh();

Тем не менее, это не значит, что, возможно, вам не следует прислушиваться к идеям сверху: -)

0 голосов
/ 04 августа 2010

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

Другими словами, все, что делает обработчик RunWorkerCompleted, это ставит в очередь первый пакет для добавления в отдельное сообщение. Метод добавления затем добавит элементы и поставит в очередь следующий пакет. Это будет продолжаться до тех пор, пока не останется больше элементов для добавления. В этот момент вы снова включите соответствующую часть вашего пользовательского интерфейса (ListView).

...