#c# #wpf #multithreading #task-parallel-library
#c# #wpf #многопоточность #задача-параллельная-библиотека
Вопрос:
Я пытаюсь сделать свой пользовательский интерфейс более отзывчивым в моем приложении WPF. Я создаю новый поток, используя
Task.Factory.StartNew( () => RecurseAndDeleteStart() );
В этом методе RecurseAndDeleteStart()
я хочу обновить метку в пользовательском интерфейсе с удаляемым файлом.
Как это сделать?
Ответ №1:
Поскольку это WPF, вы можете использовать диспетчер и вызов Dispatcher.BeginInvoke
, чтобы перенаправить обратный вызов в поток пользовательского интерфейса для обновления метки.
В качестве альтернативы вы можете передать TaskScheduler в свой метод и использовать его для обновления метки следующим образом:
// This line needs to happen on the UI thread...
TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Factory.StartNew( () => RecurseAndDeleteStart(uiScheduler) );
Затем, внутри вашего метода, когда вы хотите обновить метку, вы могли бы сделать:
Task.Factory.StartNew( () =>
{
theLabel.Text = "Foo";
}, CancellationToken.None, TaskCreationOptions.None, uiScheduler);
Это вернет вызов обратно в контекст синхронизации потока пользовательского интерфейса.
Комментарии:
1. Идеально! Именно то, что я искал.
2. 1 за то, что показал, что дочерняя задача может быть запущена в другом планировщике (и еще 1 за то, что показал мне
CancellationToken.None
— я проходилnew CancellationToken()
, но это показалось взломом!)3. 1 Это решение простое, и мне не пришлось многое менять в моем проекте, чтобы реализовать его! Попробовал несколько других решений, но не смог реализовать их корректно.
Ответ №2:
Вы должны использовать label.Dispatcher.BeginInvoke(delegate)
для вызова чего-либо из другого потока, что изменит содержимое метки.