Я пробовал простой пример асинхронного ожидания с .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
}); }));
}
Пауза в отладчике и просмотр трассировки стека. – SLaks
Это не действие Action (() => {}), которое приостанавливает ваш пользовательский интерфейс. Это 'Task.Delay (2000)', который не имеет 'ConfigureAwait (false)'. Поскольку он настроен на запуск в потоке пользовательского интерфейса, ваш поток пользовательского интерфейса будет висеть в течение 2 секунд в неустановленное время. Это неуказанное время оказывается пробегом в случае 2. –
@RaymondChen: ожидаемая задержка и вовсе не замерзает. Только после добавления пустого действия. – Gerard