Во-первых, почему вы хотите избежать DoEvents()
?
Во-вторых, вы используете противоречивые термины.
ожидание == блокировка
Вы говорите, что не хотите заблокировать поток пользовательского интерфейса, но вы do хотите дождаться завершения задачи. Это взаимоисключающие государства. Если вы ожидаете чего-то, чтобы закончить, вы блокируете свой поток.
Если вы хотите, чтобы пользовательский интерфейс действительно был годен к употреблению (не заблокирован), тогда вы не ждете , пока ваша задача не завершится. Просто зарегистрируйте обработчик события, чтобы он срабатывал после его завершения. Например, для BackgroundWorker обработайте событие RunWorkerCompleted . Для Задачи вы можете использовать продолжение для отправки обратного вызова в ваш основной поток.
Но, похоже, вы просто хотите, чтобы пользовательский интерфейс обновлялся, а не использовался. Обычно это имеет смысл, только если вы хотите, чтобы индикатор выполнения или какая-либо другая анимация пользовательского интерфейса продолжали двигаться. В этом случае я бы открыл модальное диалоговое окно, запустил свою задачу и затем подождал, пока, да, вызовет DoEvents ().
var dialog = new MessageBoxFormWithNoButtons("Please wait while I flip the jiggamawizzer");
dialog.Shown += (_, __) =>
{
var task = Task.Factory.StartNew(() => WriteToDatabase(), TaskCreationOptions.LongRunning);
while (!task.Wait(50)) // wait for 50 milliseconds (make shorter for smoother UI animation)
Application.DoEvents(); // allow UI to look alive
dialog.Close();
}
dialog.ShowDialog();
Модальное диалоговое окно не позволяет пользователю делать что-либо, но любая анимация все равно будет работать из-за того, что DoEvents () вызывается 20 раз в секунду (или более).
(Возможно, вы захотите добавить специальную обработку для разных состояний завершения задачи, но это не по теме.)