#c_sharp #многопоточность #асинхронность #async_await
На этот вопрос уже даны ответы здесь: Работа с контролами из фонового потока (2 ответа) Закрыт 3 года назад. Как работать с gui из Async? Ну вот например : есть progressbar и есть button у которого на событии Async onclick лежит следующий код Await Task.Run((){progressbar.value = 77}) и он конечно же "вылетает", так вот, что мне делать?
Ответы
Ответ 1
Самый простой вариант — если вы уж находитесь в async-функции, то не вызывайте Task.Run раньше времени. Например, вы можете сделать как-то так: async void OnClick(object sender, RoutedEventArgs e) { button.IsEnabled = false; for (int i = 0; i < 10; i++) { // выгружаем в фоновый поток ту операцию, которая должна быть асинхронной bool isGood = await Task.Run(() => ComputePart(i)); // остаток кода продолжает бежать в UI-потоке if (isGood) progressBar.Value = i; } button.IsEnabled = true; } Ещё три варианта описаны в отличном ответе @Lightness.Ответ 2
Как вариант можно использовать SynchronizationContext. Пример: private async void ChangeProgressBar() { var uiSync = SynchronizationContext.Current; await Task.Run(() => { uiSync.Send(state => { progressbar.value = 77 }, null); }); } Также можно использовать Progress< T>. Пример: private async void ChangeProgressBar() { IProgressprogress = new Progress (value => { progressBar.Value = value; }); await Task.Run(async () => { for (int i = 0; i < 100; i++) { progress.Report(i); await Task.Delay(20); } }); } Еще один вариант это использование Dispatcher. Пример: private async void ChangeProgressBar() { await Task.Run(() => { progressBar.Dispatcher.Invoke(() => progressBar.Value = 77, DispatcherPriority.Background); }); }
Комментариев нет:
Отправить комментарий