Очевидно, ваш анализ проблемы правильный. Ваша модель представления лениво загружает данные, когда это необходимо, и этого не происходит до обратного вызова Dispatcher, когда вы снова возвращаетесь в поток пользовательского интерфейса и все блокируется.
На мой взгляд, решение состоит в том, чтобы выполнить многопоточность на уровне доступа к данным:
Для коллекций: вы можете определить специальные коллекции, которые возвращают только элементы, которые уже были загружены из вышестоящего источника данных, а затем инициировать загрузку дополнительных элементов в отдельном потоке, когда кто-то подписывается на INotifyCollectionChanged. Когда дополнительные элементы поступят, инициируйте события INotifyCollectionChanged. Если INotifyCollectionChanged отписан, отмените все ожидающие загрузки.
Для итогов и тому подобного: та же идея. По мере того, как данные поступают, общее увеличение и события происходят (автоматически для DependencyProperty или с использованием INotifyPropertyChanged).
Кроме того, уровень данных должен иметь параллельное свойство для каждой коллекции, суммы или другого загруженного с задержкой значения, указывающего, полностью ли оно загружено или нет, что позволяет пользовательскому интерфейсу выделять серые участки, которые не загружены полностью. Также удобно иметь общий флаг «загрузки», который можно использовать для выделения серого цвета в разделах пользовательского интерфейса, когда загружается что-либо вообще (так проще написать пользовательский интерфейс).
Обратите внимание, что иногда операция должна блокироваться, пока не будут получены фактические данные. Я думаю, что в этом случае проще всего обеспечить методы на уровне данных для принудительной загрузки данных синхронно.