首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF DataGrid和IAsyncEnumerable项目

WPF DataGrid和IAsyncEnumerable项目
EN

Stack Overflow用户
提问于 2021-09-25 17:33:40
回答 1查看 309关注 0票数 3

有可能吗?多么?

我有一个从数据库中获取行数据的异步方法。我的结果是IAsyncEnumerable<TItem>。但是,对于快速响应的UI来说,它应该是一个完美的数据类型--当我将它设置为网格的数据源时,它就不工作了,什么也没有显示。

我有两个解决办法。首先,显然是从我的异步任务返回数组。第二个是类似的--我只需对结果使用ToArrayAsync() (来自System.Linq.Async)。

我怀疑使用ToArrayAsync()比从任务返回数组要慢,所以这没有什么意义。

如果IAsyncEnumerable类型可以直接用作控件的数据源,这将是非常有意义的。但是,我可能需要实现某种IObservable接口或类似的东西。有人试过这个吗?

整件事都是很新的,我找不到任何例子,甚至一篇文章都说这是可能的。我的意思是-如果您不能将它用于UI,那么IAsyncEnumerable有什么好处呢?

更新:我想要的是IAsyncEnumerable<TItem>ObservableCollection<TItem>之间的转换。我找到了示例,但它们都与我提到的解决方法完全相同--因此数据被放入数组中,然后添加到集合中。这就破坏了所有IAsyncEnumerable<T>的好处。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-25 20:33:38

引入IAsyncEnumerable是为了允许异步数据生成器/数据流。通常,显示数据项集合的ItemsControl之类的控件是基于索引的。和基于ICollectionView的。

通常,控件通过原始集合的ICollectionView获取项。由源集合的ICollectionView中的索引标识的数据项被包装到UIElement容器中以进行呈现。

数据流/生成器不是基于索引的。Enumerator (调用IEnumerable.GetEnumerator的结果)通过调用IEnumerator.MoveNext (foreach是一种为方便封装涉及IEnumerator的实际枚举逻辑的语言构造)从一个元素过渡到另一个元素。

除了异步数据流可能带来的线程问题之外,基于索引的ItemsControl还需要预先知道它的所有项--这就是为什么您需要一个实现INotifyCollectionChanged的集合才能让ItemsControl更新其更改的Items:视图被认为是被动的--它只显示数据而不生成数据。

虽然不是强制性的,但WPF的设计考虑到了MVVM。活动部分通常是模型或视图模型。数据生成通常在模型中进行。因此,将IAsyncEnumerable作为直接绑定源是没有意义的,因为这意味着被动UI元素必须直接生成/使用数据流。您可能希望这是视图模型/Binding.Source的责任。同样,UI的设计是为了处理ICollectionView实现,而不是直接处理集合及其迭代器。

您可以做的是枚举Binding.Source中的Binding.Source并用生成的结果更新ObservableCollection

代码语言:javascript
复制
public ObservableCollection<DataItem> ItemsSourceForDataGrid { get; }

private async Task GenerateDataItemsAsync(IAsyncEnumerable asyncDataStream)
{
  // Keep the GUI responsive while consuming an e.g. CPU intensive generator
  await foreach (DataItem item in asyncDataStream)
  {
    this.ItemsSourceForDataGrid.Add(item);
  }
}

还请注意,像ToListAsyncToArrayAsync这样的扩展方法可能会锁定应用程序。如果您不知道数据源(即生成器),则在ToListAsync试图最后确定数据流时,您可能会锁定应用程序。但是,按照定义,数据流可能是无限的,这将导致ToListAsync永远不返回或完成返回的Task对象。如果您发现自己需要ToArrayAsync,并且您是数据生成器的作者,那么首先您可能不应该使用IAsyncEnumerable。像ToArrayAsync这样的异步终结器违背了IAsyncEnumerable的思想。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69328565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档