Проблема, я полагаю, в том, что вы не до конца понимаете, что здесь происходит в системе.
Когда ваше переднее окно (диалоговое окно) закрывается, фоновое окно (форма) получает фокус и толщину, чтобы перекрасить область отсечения, где находилось диалоговое окно. Это происходит с помощью вызова PostMessage, который отправляет сообщение Windows, которое должно быть извлечено, переведено и отправлено в недрах вызова Application.Run.
По своей природе это довольно медленный процесс, поскольку пользовательский интерфейс не должен вытеснять важные вещи.
Если вы выполняете интенсивную обработку сразу после того, как это PostMessage происходит, обработка этих сообщений Windows часто может быть замедлена, в результате пользовательский интерфейс выглядит «заблокированным» или рисует очень медленно. Это усугубляется, если выполняемая вами обработка выполняется в том же потоке, что и пользовательский интерфейс.
Почему ваши усилия не улучшают ситуацию?
- Вызов Refresh просто отправляет другое сообщение. Теперь это сообщение поступает в очередь на обработку, поэтому на самом деле все будет еще хуже.
- Вызов Invalidate делает почти то же самое, что и Refresh, только асинхронно. Опять же, все ухудшается.
- DoEvents указывает насосу сообщений выводить, переводить и отправлять сообщение. Эта диспетчеризация все еще должна быть обработана в потоке пользовательского интерфейса, так что это будет происходить до тех пор, пока поток не успеет выполнить работу (т.е. после вашей обработки)
Итак, как нам это "исправить"?
Первым шагом часто является помещение обработки в отдельный поток, чтобы планировщик мог циклически выполнять задачи между пользовательским интерфейсом и потоками обработки, вплоть до кванта по умолчанию. Это означает, что обработка может истощать пользовательский интерфейс только в течение максимум 100 мс, прежде чем разрешается выполнение какого-либо вида рисования (при условии равного приоритета потока).
new Thread(PerformHeavyLoginTasks)
{
IsBackground = true
}.Start();
Вы можете пойти еще дальше и дать интерфейсу «быстрый старт» при обработке (в данном примере 10 мс):
new Thread(new ThreadStart(delegate
{
Thread.Sleep(10);
PerformHeavyLoginTasks();
}))
{
IsBackground = true
}.Start();
Конечно, это может означать, что теперь вам нужно асинхронно обрабатывать следующее «отображение», если отображаемый пользовательский интерфейс зависит от результата обработки. Существует множество онлайн-ресурсов по асинхронным шаблонам, поэтому я не буду бить эту мертвую лошадь здесь.