Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
// ...
EnableWindow(handle, false);
DispatcherFrame frame = new DispatcherFrame();
this.Closed += delegate
{
EnableWindow(handle, true);
// ...
BOOL fIsWindowEnabled = ! EnableWindow( handle, false );
// ...
EnableWindow( handle, fIsWindowEnabled );

Кажется, вы сделали не совсем то что задумывалось.
Вызов Dispatcher.PushFrame, конечно же, запускает новый цикл — вот только он запускается в текущем потоке. А вы только что перешли в пул потоков вызовом Task.Factory.StartNew! В итоге у вас работают два цикла сообщений, причём второй цикл работает полностью вхолостую, ведь к нему не привязано ни одного окна. И это вам ещё повезло что никаких проблем с многопоточностью не словили...
Вторая ошибка — вы каждый раз подписываетесь на ButtonClicked, а кто отписываться будет?
Правильнее для таких задач использовать асинхронность и TaskCompletionSource:
public async Task<string> GetInput()
{
var tcs = new TaskCompletionSource<string>();
Action handler = () => tcs.SetResult(Text);
try
{
ButtonClicked += handler;
return await tcs.Task;
}
finally
{
ButtonClicked -= handler;
}
}
public RelayCommand ButtonClick => new RelayCommand(async () =>
{
await Task.Run(() => {
// имитация работы
Thread.Sleep(1000);
});
var control = new PopupControlModel();
Result = await control.GetInput();
await Task.Run(() => {
// имитация дальнейшей работы
Thread.Sleep(1000);
});
});
C# WPF аналог Window.ShowDialog() или разбираемся с DispatcherFrame