C# WPF使用异步方法更新列表框中的itemssource
我有一个列表框,希望将其ItemsSource设置为我从云中获取的可观察集合。我必须等待此传入集合,它导致我的itemssource无法更新 这是我的方法。 这是我的xaml.cs构造函数:C# WPF使用异步方法更新列表框中的itemssource,c#,wpf,asynchronous,listbox,async-await,C#,Wpf,Asynchronous,Listbox,Async Await,我有一个列表框,希望将其ItemsSource设置为我从云中获取的可观察集合。我必须等待此传入集合,它导致我的itemssource无法更新 这是我的方法。 这是我的xaml.cs构造函数: { InitializeComponent(); GetEmployeeList(); } 以及它调用的方法: private async void GetEmployeeList() { await EmployeeController.GetAllEmployees().Con
{
InitializeComponent();
GetEmployeeList();
}
以及它调用的方法:
private async void GetEmployeeList()
{
await EmployeeController.GetAllEmployees().ContinueWith(r =>
{
_employees = (r.Result);
EmployeeListBox.ItemsSource = _employees;
});
}
My EmployeeController.GetAllEmployees()返回一个ObservableCollection。而且_EmployeeListBox会更新,但是我的EmployeeListBox不会显示这些对象。我试过使用静态硬编码集合,但效果很好——这是因为我的异步吗?
有人有什么建议吗
-
谢谢。我想你有一个“交叉线程”问题。
当您执行异步代码时,它会在另一个线程中运行,而这个新线程没有访问用户界面(UI)的权限,因为控件属于用户界面线程。
解决方案是在可能的情况下,温和地要求UI执行代码:
你必须使用调度器
this.Dispatcher.BeginInvoke(new Action(() =>
{
// - Change your UI information here
}), null);
有时,这种类型的错误是不可见的。这就是很难诊断的原因。
您可以通过在为回调执行的代码周围添加Try…Catch
来查看它
请注意,您可以将项目源用作IEnumerable,并对每个值使用收益率返回值假设您确定正在调用continueWith,那么您的continueWith代码块很可能发生在none UI线程上 一个选项是为延续设置CurrentSyncronizationContext(下面的示例)。这将要求继续代码在启动原始任务的同一线程上执行。或者,您需要在UI线程上调用代码,最常用的方法是使用Dispatcher
private async void GetEmployeeList()
{
await EmployeeController.GetAllEmployees().ContinueWith(r =>
{
_employees = (r.Result);
EmployeeListBox.ItemsSource = _employees;
},
TaskScheduler.FromCurrentSynchronizationContext());
}
但是,由于您使用的是等待,并且是从UI线程调用的,因此您也可以将等待的结果设置为ItemSource direct:
private async void GetEmployeeList()
{
EmployeeListBox.ItemsSource = await EmployeeController.GetAllEmployees();
}
。。。这也很好地演示了async/await关键字为您节省了编写代码的时间:)如果您将等待的结果存储在一个变量中,然后分配它,您应该避免交叉线程
private async void GetEmployeeList()
{
var emps = await EmployeeController.GetAllEmployees();
EmployeeListBox.ItemsSource = _emps;
}
调用
async
方法不会导致在另一个线程中调用它。您将TPL之类的东西与async/await混淆了。@DanielKelley:我认为任何async/await操作都会在另一个线程上调用其回调,请参阅Olite answer,其中也谈到了非UI线程。MS编写的async/await只是语法上的糖类。我们看到一个简单的“Thread.Timer”在另一个线程中引发了“appeased”。很抱歉,我们的评论太晚了,我们遇到了服务器问题。但我们终于能够测试这个,它就像一个符咒。谢谢