Асинхронный метод работает слишком быстро, чтобы обновить мой список в основном потоке
У меня есть кнопка WPF и список. когда я нажимаю кнопку, он использует асинхронность и ожидает запуска генератора чисел. Генератор чисел — это просто цикл for, производящий целые числа. Также в цикле находится Iprogress, сообщающий целое число. Функция в основном потоке обновляет listBox в пользовательском интерфейсе.
Проблема в том, что список не обновляется правильно, однако, если я помещаю Thread.sleep(10) в цикл for, он работает нормально. Похоже, что поток генерирует отчеты слишком быстро для обновления списка. Как я могу покончить с Thread.sleep(10) и точно обновить список? Правильно ли я подхожу к этому? Может кто-нибудь помочь? Спасибо.
public partial class MainWindow : Window
{
Progress<ProgressReportModel> progress = new Progress<ProgressReportModel>();
public MainWindow()
{
InitializeComponent();
progress.ProgressChanged += ReportProgress;
}
private async void generateNumbersButton_Click(object sender, RoutedEventArgs e)
{
await Task.Run(()=>NumberGenerator.SimpleNumberGenerator(progress));
}
private void ReportProgress(object sender, ProgressReportModel e)
{
numbersListBox.Items.Add($"Integer generated {e.LastIntegerGenerated.ToString()}");
}
}
static class NumberGenerator
{
static public void SimpleNumberGenerator(IProgress<ProgressReportModel> progress)
{
ProgressReportModel report = new ProgressReportModel();
int number = 10;
for (int i = 0; i <= number ; i++)
{
report.LastIntegerGenerated = i;
progress.Report(report);
//Thread.Sleep(10);
}
}
}
public class ProgressReportModel
{
public int LastIntegerGenerated { get; set; } = 0;
}
запустить без Thread.Sleep в цикле. Ожидание целых чисел от 0 до 10, но получение этого
запустите с Thread.Sleep(10), и числа будут зарегистрированы точно
1 ответ
По сути, проблема заключается в том, что метод ReportProgress вызывается после обновления свойства LastIntegerGenerated вашего объекта отчета.
Самый простой способ решить эту проблему — использовать новый объект отчета для каждого вызова progress.Report. Переместите строку:
ProgressReportModel report = new ProgressReportModel();
быть в вашем цикле for, и вам больше не нужно вставлять эту задержку.