我有一个 WPF 应用程序,其中数据库视图显示在
DataGrid
中。我实现了分页。当我转到下一页时,我查询数据库并刷新视图模型中的ObservableCollection
。后者大约需要2s(没有查询)。在自定义 ObservableCollection
的帮助下,视图只会收到一次通知。
如果我创建测试数据而不是数据库查询,则刷新只需要 0.2 秒。我想用真实数据达到这个刷新时间。
我尝试了
AsNoTracking
查询,但没有帮助。我尝试将 EF 代理类转换为 poco 类,但没有结果。 然后我意识到如果我查询数据库但我不使用结果而是测试数据那么刷新仍然是2s。这很奇怪。可能是 EF 调用造成了一些混乱,这就是后续指令速度较慢的原因。 GC.Collect();
没有帮助。
dbViewItems = await DbViewSelectorOld(dbContext).FromSql(dbScript).AsNoTracking()
.Where(WhereCondition).OrderBy(OrderByCondition)
.Skip(numberOfRowsToBeSkipped).Take(numberOfRowsToBeTaken)
.ToListAsync().ConfigureAwait(false);
var stopWatch = new Stopwatch(); // start of the refresh
stopWatch.Start();
var displayClassItems = dbViewItems.Select(FromViewClassCreateDisplayClass).ToList();
DisplayedRows.ClearWithSingleNotification();
DisplayedRows.AddRangeWithSingleNotification(displayClassItems);
DisplayedRowsBackup.Clear();
DisplayedRowsBackup.AddTheCopy(displayClassItems);
Console.WriteLine(stopWatch.ElapsedMilliseconds);
DisplayedRows
是ItemsSource
,我也有一个备份。有什么想法吗?
ConfigureAwait(false)
允许await 之后的代码从线程池而不是UI 线程运行。这可用于提高性能并避免不必要的同步。
但在 UI 程序中,这种同步是重要。我们只被允许从 UI 线程修改 UI 对象,因此我们希望运行时将执行同步回 UI 线程,这样我们就可以使用结果来更新 UI。
一般来说,我建议不要使用
ConfigureAwait(false)
,除非你有特定的理由这样做。来自 ConfigureAwait 常见问题解答
什么时候应该使用ConfigureAwait(false)?
这取决于:您是在实现应用程序级代码还是通用库代码?
在编写应用程序时,您通常想要默认行为(这就是为什么它是默认行为)。如果应用程序模型/环境(例如 Windows Forms、WPF、ASP.NET Core 等)发布了自定义 SynchronizationContext,那么几乎可以肯定它这样做有一个很好的理由:它为关心同步上下文的代码提供了一种交互方式适当的应用程序模型/环境。因此,如果您在 Windows 窗体应用程序中编写事件处理程序、在 xunit 中编写单元测试、在 ASP.NET MVC 控制器中编写代码,无论应用程序模型实际上是否发布了 SynchronizationContext,您都希望使用它SynchronizationContext(如果存在)。这意味着默认/ConfigureAwait(true)。您可以简单地使用await,并且关于回调/延续被发布回原始上下文(如果存在),正确的事情就会发生。这导致了以下一般指导:如果您正在编写应用程序级代码,请不要使用ConfigureAwait(false)