Приложение перестает отвечать на запросы при добавлении тысяч строк - PullRequest
0 голосов
/ 13 марта 2011

У меня есть приложение Windows Forms, которое создает фоновый поток для поиска в файлах и добавляет соответствующие имена файлов в DataGridView. Фоновый поток использует BeginInvoke для добавления строк в DataGridView, и все работает нормально, если фоновый поток не возвращает тысячи результатов. Пользовательский интерфейс работает отлично, даже если фоновый поток обрабатывает тысячи файлов, если только он не пытается добавить несколько тысяч строк в DataGridView.

Я попытался добавить строки одну за другой, буферизовать их и добавить 100 строк одновременно. Но интерфейс приложения перестает отвечать на запросы. Фоновый процесс работает быстрее, чем поток пользовательского интерфейса, и всегда есть новые строки для добавления в DataGridView.

Я даже попробовал Application.DoEvents (в потоке пользовательского интерфейса), но это тоже не помогло.

Есть идеи? Можно ли это исправить без добавления задержки в фоновый поток?

Заранее спасибо

Ответы [ 5 ]

2 голосов
/ 13 марта 2011

Похоже, что использование Invoke вместо BeginInvoke для добавления строк является самым простым решением. Это немного замедляет фоновый поток, но не позволяет интерфейсу перестать отвечать на запросы. Поскольку вы не добавляете заранее заданную задержку в фоновый поток, я думаю, что может быть приемлемо немного замедлить фоновый поток только для того, чтобы позволить потоку пользовательского интерфейса наверстать упущенное. Использование SuspendLayout и ResumeLayout также не помогло при использовании BeginInvoke. Я еще не пробовал виртуальный режим с общими строками, но это тоже может помочь.

2 голосов
/ 13 марта 2011

Убедитесь, что вы вызываете SuspendLayout() и ResumeLayout() до и после добавления всех новых строк соответственно. Не вызывая SuspendLayout перед добавлением всех строк, DataGridView будет перекрашиваться после каждой добавленной строки, что немного замедляет работу.

1 голос
/ 13 марта 2011

Попробуйте использовать виртуализацию данных: http://msdn.microsoft.com/en-us/library/ms171622.aspx

0 голосов
/ 30 марта 2011

Мне показалось, что проблема в том, что полосы прокрутки перекрашиваются каждый раз, когда добавляется строка, если я добавлю, скажем, 10000 строк. Я решил эту проблему, установив полосы прокрутки в datagridview в None перед заполнением и восстановив после заполнения, как показано ниже:

ScrollBars bars = this.ScrollBars; this.ScrollBars = System.Windows.Forms.ScrollBars.None;

... заполнить здесь (у меня есть переопределенный элемент управления DataGridView)

this.ScrollBars = bars;

SuspendLayout почему-то не работает в случае добавления тысяч строк.

0 голосов
/ 13 марта 2011

Один из способов состоит в том, чтобы основной поток создал BlockingCollection<string>, который служит в качестве очереди, в которую фоновый поток может добавлять строки.Когда фоновый поток завершает добавление, он вызывает CompleteAdding.

Поток пользовательского интерфейса также создает таймер, который срабатывает с некоторой частотой (вероятно, которую вы определили экспериментально).Событие таймера Elapsed проверяет, есть ли что-нибудь в очереди, и, если это так, удаляет один элемент и добавляет его в DataGridView.Когда событие таймера Elapsed видит, что свойство очереди IsComplete равно True, оно останавливается и удаляет таймер.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...