【发布时间】:2021-04-06 21:50:22
【问题描述】:
我有一个主窗口,上面有一个 TextBlock 和一个 Button 控件,通过单击调用 RunAsync(int) 方法.它正在做一些计算,所以这个过程花费了相当长的时间并阻塞了 UI。我能够将它移动到异步线程,但我完全坚持如何最好地实现在 For 循环的每次迭代中从该方法更新接口。例如,使用进度条。
目前我有以下代码:
public partial class MainWindow : Window
{
public MainWindow() => InitializeComponent();
private async Task<List<int>> RunAsync(int par)
{
return await Task.Run(() =>
{
List<int> list = new List<int>();
for (int i = 0; i < par; i++)
{
// some code, that takes quite a long time
Thread.Sleep(500);
list.Add(i);
}
return list;
});
}
private async void StartBtn_Click(object sender, RoutedEventArgs e)
{
int count = (await RunAsync(5)).Count;
label.Text = count.ToString();
}
}
【问题讨论】:
-
2 件事:1 而不是 Thread.Sleep... 你应该使用 Task.Delay。 2:使用 Dispatcher 从不同的线程更新 UI
-
... 或简单地使用绑定...从某个实现 INotyfiPropertyChanged 的类中绑定属性并将其实例设置为 MainWindow 的 DataContext ...然后从工作线程更新此属性...就是这样
-
您甚至可能不需要调用 Dispatcher。只需将异步调用移动到循环体中,即运行并等待异步方法并在每次循环迭代中更新 UI。
-
您可能想看看
Progress<T>类和how it's used。另一个有用的教程是here。 -
等待线程有一个 SynchronizationContext,所以当 Task.Run 准备好时它会返回到那个线程。无需调用任何东西。
标签: c# wpf asynchronous async-await