Обычно это не происходит в чистых приложениях WPF. Ситуации, которые я видел, где это происходит:
- Ваш поток пользовательского интерфейса выполняет некоторый долго выполняющийся код и не обрабатывает сообщения
- В драйверах видео есть ошибка
- Используется прозрачность окна, эта часть окна прозрачна, и приложение, не относящееся к WPF, отвечает за его рисование
- Вы интегрируете WPF с технологиями, не относящимися к WPF, такими как GDI (например, MFC), GDI + (например, WinForms) или DirectX, а область, в которой возникают проблемы при рисовании, должна быть окрашена другой технологией. Это включает в себя элементы управления Frame и MediaPlayer, которые используют не-WPF технологии под капотом.
Решения могут быть разными:
- В случае 1 и обычно в случае 4 проблема часто очевидна, и решение, как правило, заключается в устранении проблем с многопоточностью. Если проблема с многопоточностью не очевидна, сбой в отладчике, предложенный Хансом Пассантом, может выявить длительную операцию, о которой вы не знали, например, доступ к базе данных.
- В случае 2 вы можете диагностировать его, временно переключившись на рендеринг программного обеспечения, и исправить его, обновив драйверы видео.
- В случае 3 вы ничего не можете сделать, если другое приложение не перекрасится, но пользователи должны признать, что это не проблема с вашим программным обеспечением.
- В случае 4, если проблема с потоками не очевидна, обычно полезно выделить не-WPF-код и посмотреть, какие потоки обработки сообщений активны.
Обратите внимание, что выполнение длительных операций в потоке пользовательского интерфейса, как правило, является плохой идеей, и если вам необходимо выполнять такие операции, ваше приложение должно быть многопоточным. Однако, если ваше приложение работает быстро и грязно, или вы все еще в порядке с полной блокировкой пользовательского интерфейса, вы можете решить только проблему рисования, убедившись, что очередь Диспетчера полностью очищена перед началом вашей длительной операции. Это делается путем запуска пустого вызова Dispatcher с низким приоритетом, в результате чего сначала выполняются все операции с более высоким приоритетом. Например:
Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {}));