Разбить загрузку данных на более мелкие куски, скажем, от 100 до 1000 строк за раз. Если сетка WPF привязывает данные к вашему сбору данных, а коллекция является наблюдаемой коллекцией (реализует INotifyCollectionChanged), WPF автоматически обновит отображение, когда новые данные будут добавлены в коллекцию.
Вы также должны рассмотреть возможность использования виртуализированных элементов управления списком или сеток в сочетании с источниками данных поискового вызова, так что будут загружены только данные, которые в настоящее время отображаются на экране (вместо 1,2 миллиона строк данных в памяти). Это позволит вам выполнить «chunking» и позволит вам представить в основном бесконечное количество данных для пользователя с очень небольшим использованием памяти или сетевым лаг.
Проверить эту SO статью о получении данных в асинхронном режиме для виртуального ListBox: How do I populate a ListView in virtual mode asynchronously?