Правильно используйте Диспетчер.
Вы должны добавить вещи в свой ListBox (или его источник данных) из потока Dispatcher, иначе пользовательский интерфейс взорвется. Когда вы делаете это, вы либо находитесь в методе в этом потоке, либо (возможно, более вероятно) в фоновом потоке и используете Dispatcher.BeginInvoke
для добавления элемента.
Когда вы отправляете обновление Диспетчеру, используйте Dispatcherpriority.Normal
в качестве приоритета. Диспетчер имеет очередь рабочих элементов, и ваши Normal
элементы будут выдвигаться (возможно, на удивление) высоко в этой очереди.
Бит кода, который WPF запускает для обновления привязки данных, когда базовые данные были изменены, работает в DispatcherPriority.DataBind
, что ниже Normal
. Это означает, что привязка данных, как правило, не будет обновляться до тех пор, пока не будут добавлены все ваши элементы (или, альтернативно, если добавление ваших элементов занимает много времени, это может произойти, когда диспетчер бездействует между добавлением элементов).
Бит кода, который фактически отображает ваш элемент управления (скажем, когда его привязка сигнализирует об обновлении), работает на DispatcherPriority.Render
и имеет даже более низкий приоритет, чем привязка. Это означает, что ваш элемент управления будет отображаться только тогда, когда в Dispatcher закончились привязки для обновления, что, в свою очередь, произойдет только тогда, когда в Dispatcher закончится добавление элементов в процесс.
Если это звучит странно, помните, что каждый слой (update - binding - render) вызывает метафорический флаг для слоя ниже - вы не получаете десять привязок, а затем происходит десять визуализаций. Если вы быстро добавите свой предмет, вы получите все ваши добавления, за которыми следует одно связывание и одно рендеринг - что идеально.
По сути: если вы используете Диспетчер как он задумывался, вам не о чем беспокоиться. Кажется «неправильным» иметь рендеринг как относительно низкий приоритет для Dispatcher, но на самом деле это очень умно: -)