Используйте Progress<T>
, чтобы сообщить о прогрессе, и Task.Run
, чтобы переместить обработку в фоновый поток.
Если вы не переместите обработка в фоновом потоке, это произойдет в потоке пользовательского интерфейса. Это означает, что поток пользовательского интерфейса занят выполнением вашей обработки и поэтому не может обновить индикатор выполнения (и ваше приложение будет выглядеть замороженным).
Progress<T>
позволяет вам определить действие, которое вызывается каждый раз, когда О прогрессе сообщается с использованием метода Report
на соответствующем интерфейсе IProgress<T>
, который мы будем использовать для обновления индикатора выполнения. Это также гарантирует, что это действие вызывается в потоке пользовательского интерфейса 1 независимо от того, из какого потока вызывается его метод Report
. Это означает, что безопасно вызывать Report
из нашего фонового потока, и наш индикатор выполнения все равно будет обновляться из потока пользовательского интерфейса.
public class WorkerClass
{
public void doSomething(string filePath, IProgress<int> progress)
{
using (var package = new Package(filePath))
{
foreach (var item in package)
{
updateMethod(item); //once this method call is complete I want the ProgressBar to update its Value
progress.Report(...);
}
}
}
}
private async void btnUpload_Click(object sender, RoutedEventArgs e)
{
progressBar.Value = 10;
var progress = new Progress<int>(x => progressBar.Value = x);
string filePath = txtFilePath.Text;
WorkerClass worker = new WorkerClass();
await Task.Run(() => worker.doSomething(filePath, progress));
progressBar.Value = 100;
}
1 Строго он захватывает текущий SynchronizationContext при его создании и использует его при вызове действия, переданного его конструктору. Если он построен в потоке пользовательского интерфейса, это означает, что действие вызывается в потоке пользовательского интерфейса.