简体   繁体   English

用进度更新异步ObservableCollection

[英]updating an async ObservableCollection with progress

My problem is that my task is changing an observable collection that is data-bound to a UI element. 我的问题是我的任务是更改与数据绑定到UI元素的可观察集合。 my task will report progress and this data will be updated to the ui via the observable collection : 我的任务将报告进度,并且该数据将通过observable collection更新到ui:

async private void getProductData()
{
    await Task.Run(() => getTableDataFromDb(new Progress<string>(
       data => _prc.Add(new ProductList() { Taxe = data })
       ), "List"));
}
private void getTableDataFromDb(IProgress<string> progress, string tabelName)
{
   //simple exemple
   for(var i =0; i < 100; i++)
     progress.Report( "test"+i);
}

if i run this code i get this error: 如果我运行此代码,则会出现此错误:

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread. 这种类型的CollectionView不支持从与Dispatcher线程不同的线程对其SourceCollection进行更改。

How can i access the main thread to update this collections? 我如何访问主线程来更新此收藏集? Thanks 谢谢

The problem is that you are creating the Progress<string> object in the wrong thread. 问题是您在错误的线程中创建Progress<string>对象。 It's being created in the same worker thread that's actually doing the work, which means it doesn't capture the correct SynchronizationContext object to marshal the work back to the thread you want. 它是在与工作实际相同的工作线程中创建的,这意味着它没有捕获正确的SynchronizationContext对象来将工作编组回所需的线程。

Instead, you want something like this: 相反,您需要这样的东西:

async private void getProductData()
{
    IProgress<string> progress = new Progress<string>(
       data => _prc.Add(new ProductList() { Taxe = data }));

    await Task.Run(() => getTableDataFromDb(progress, "List"));
}

That will create the Progress<string> object in the thread that calls the getProductData() , which is presumably your UI thread. 这将在调用getProductData()的线程中创建Progress<string>对象,该对象可能是您的UI线程。 Then when the IProgress<string>.Report() method is called, the delegate invocation will be marshalled back to the UI thread as intended. 然后,当调用IProgress<string>.Report()方法时,将按预期将委托调用编组回UI线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM