使用进度更新异步ObservableCollection

时间:2016-07-21 02:59:43

标签: c# wpf async-await observablecollection

我的问题是我的任务是更改数据绑定到UI元素的可观察集合。 我的任务将报告进度,此数据将通过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);
}

如果我运行此代码,我会收到此错误:

  

此类型的CollectionView不支持对其进行更改   来自与Dispatcher线程不同的线程的SourceCollection。

如何访问主线程来更新此集合? 感谢

1 个答案:

答案 0 :(得分:3)

问题是您在错误的线程中创建Const FOR_READING = 1 Const FOR_WRITING = 2 strFileName = "C:\scripts\test.txt" Set objFS = CreateObject("Scripting.FileSystemObject") Set objTS = objFS.OpenTextFile(strFileName, FOR_READING) strContents = objTS.ReadAll objTS.Close arrLines = Split(strContents, vbNewLine) Set objTS = objFS.OpenTextFile(strFileName, FOR_WRITING) For i= 0 To UBound(arrLines) If ShouldSkip(i) Then objTS.WriteLine arrLines(i) End If Next Function ShouldSkip(i) Dim arrSkipLines, x arrSkipLines = Array(1, 22, 32, 42, 169) For Each x In arrSkipLines If x = i Then ShouldSkip = True Exit Function End If Next ShouldSkip = False End Function 对象。它是在实际工作的同一个工作线程中创建的,这意味着它不会捕获正确的Progress<string>对象来将工作编组回到你想要的线程。

相反,你需要这样的东西:

SynchronizationContext

这将在调用async private void getProductData() { IProgress<string> progress = new Progress<string>( data => _prc.Add(new ProductList() { Taxe = data })); await Task.Run(() => getTableDataFromDb(progress, "List")); } 的线程中创建Progress<string>对象,这可能是您的UI线程。然后,当调用getProductData()方法时,委托调用将按预期编组回UI线程。