2014-09-28 3 views
3

Я пробовал простой пример асинхронного ожидания с .ConfigureAwait(false) и без него.
С помощью .ConfigureAwait(false) вы можете обновить ui через диспетчер, который без него без него.
Это пример 1 и 3 в коде ниже - это работает, и я могу понять, как он работает.Действие (() => {}) через диспетчер зависает ui

Мой вопрос касается случая 2, где я добавляю - совершенно ненужно - обновить
Action(() => { }) через диспетчер.
Это время от времени зависает. Особенно после повторного вызова обработчика событий.
Может ли кто-нибудь объяснить, почему ui зависает в случае 2?

private void Test_Click(object sender, RoutedEventArgs e) 
{ 
    Test(); 
} 

public async void Test() 
{ 
    Print("Start task"); 

    // Case 1 & 2 
    await Task.Delay(2000); 
    // Case 3 
    await Task.Delay(2000).ConfigureAwait(false); 

    Print("Finished task"); 
} 

void Print(string text) 
{ 
    // Case 1 & 2 
    Output.Inlines.Add(new Run(text) { Foreground = Brushes.Blue, FontWeight = FontWeights.Bold }); 
    // Case 2 only 
    Output.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new Action(() => { })); 

    // Case 3 
    Output.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, 
     new Action(() => 
     { 
     Output.Inlines.Add(new Run(text) { Foreground = Brushes.Blue, FontWeight = FontWeights.Bold 
     }); })); 
} 
+0

Пауза в отладчике и просмотр трассировки стека. – SLaks

+3

Это не действие Action (() => {}), которое приостанавливает ваш пользовательский интерфейс. Это 'Task.Delay (2000)', который не имеет 'ConfigureAwait (false)'. Поскольку он настроен на запуск в потоке пользовательского интерфейса, ваш поток пользовательского интерфейса будет висеть в течение 2 секунд в неустановленное время. Это неуказанное время оказывается пробегом в случае 2. –

+0

@RaymondChen: ожидаемая задержка и вовсе не замерзает. Только после добавления пустого действия. – Gerard

ответ

3

Это ошибка в WPF.

Он работает отфильтрованный GetMessage() петли (см here), который will hang, если это сообщение застряли в очереди, которая не соответствует фильтру.

+0

Глядя далее, мое объяснение неверно; он фактически не фильтрует ничего. Это все еще ошибка в WPF, но я понятия не имею, почему это зависает. – SLaks

+0

@ hvd: Да; Я просто это понял. Любая идея, почему он повесился? – SLaks

+0

@SLaks Я понял, что вы поняли это, когда я увидел ваш комментарий. :) Нет, не знаю. – hvd

Смежные вопросы