我尝试使用c#的TPL异步执行一个简单的代码。但不是在一个分开的线程!我想只使用主线程,我希望我的WPF应用程序不会冻结。
这样,我不使用方法Task.Run或Task.Factory.StartNew(它们创建一个新线程)。我这样做:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var someTask = new Task<List<Person>>(() => CreateList());
await someTask;
ListBoxControl.ItemsSource = someTask.Result;
}
private List<Person> CreateList()
{
var list = new List<Person>();
list.AddRange(Enumerable.Range(1, 1000000).Select(x => new Person(x)));
return list;
}
但等待之后,它永远不会回来。我究竟做错了什么?谢谢!
答案 0 :(得分:3)
您已创建Task
,但尚未启动它。 await
等待任务完成,正如您所见,在这种情况下永远不会。
由于您不想使用后台线程,我会查看@Noseratio的评论。
答案 1 :(得分:1)
WPF等客户端用户界面中async-await
的一大好处就是从UI线程中加载非UI工作(如CPU重量级或阻止I / O)。
事实上,这正是你想要的假设的例子。
正确使用async-await
后,您的代码可以像这样简洁:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ListBoxControl.ItemsSource = await Task.Run((Func<List<Person>>)CreateList);
}
或者,如果你没有在任何地方使用CreateList:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ListBoxControl.ItemsSource = await Task.Run(
() =>
{
var list = new List<Person>();
list.AddRange(Enumerable.Range(1, 1000000).Select(x => new Person(x)));
return list;
}
);
}
如果您不需要保留列表:
private async void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
ListBoxControl.ItemsSource = await Task.Run(
() => Enumerable.Range(1, 1000000).Select(x => new Person(x))));
}
以下是一些您可以阅读的文章,以便快速了解async-await
: