我有一段测试GUI和线程行为的代码。当我查询数据库并在DataGrid中添加大量行(10K +)时,我想保持 ProgressBar 动画运行(使用IsIndeterminate="True"
)。即使我将数据库和GUI代码包装在Dispatcher.BeginInvoke
中, ProgressBar 动画也会在填充DataGrid时抖动。
我希望 ProgressBar动画能够冻结(如果在GUI线程上)或运行顺畅(如果在单独的线程上),但我无法理解动画为什么会急剧运行。
请不要建议 BackgroundWorker ,因为我想了解这个问题中的问题,以及为什么BeginInvoke没有分离线程。我只是循环遍历SqlDataReader并逐个添加到DataGrid作为Item而不是数据绑定到源或数据表。
// XAML
<Button Click="Button_Click"></Button>
<ProgressBar IsIndeterminate="True"></ProgressBar>
<DataGrid ... ></DataGrid>
// C#
private void Button_Click(object sendoer, RoutedEventArgs e)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,(ThreadStart)delegate()
{
// Query database and update GUI (e.g. DataGrid)
});
}
答案 0 :(得分:3)
Dispatcher
始终在与其关联的线程(您的案例中为UI线程)上执行代码,无论您使用Invoke
还是{{1} }(这是InvokeAsync
的便捷简写)。因此,有关从数据库加载数据和更新BeginInvoke
的所有工作都是在UI线程上完成的,因此动画并不流畅。
DataGrid
和Invoke
之间的区别在于前者是同步执行,而后者是异步执行。这意味着在第一种情况下,调用线程将被挂起,直到委托完成执行(即它将同步),而在第二种情况下,线程将继续执行而无需等待代表完成。让我试着用例子来指出这种差异。
示例I。从UI线程调用方法(如您的情况)
假设我们只有一个线程(UI线程)。调用InvokeAsync
不会产生任何明显的影响,因为代理将立即执行,然后才会继续执行。所以这个:
Invoke
将具有与此相同的效果:
Dispatcher.Invoke(() => DoSomeStuff());
DoSomeOtherStuff();
然而,调用DoSomeStuff();
DoSomeOtherStuff();
将产生这样的效果,即只有在执行了具有更高优先级(或已经安排具有相同优先级)的所有计划任务之后,才会安排委托执行。所以在这种情况下:
BeginInvoke
Dispatcher.InvokeAsync(() => DoSomeStuff());
DoSomeOtherStuff();
将首先执行,DoSomeOtherStuff()
秒。这通常用于事件处理程序,例如,只有在完全处理事件后才需要执行某些代码(例如see this question)。
示例II。从不同的线程调用方法
假设我们有两个线程 - UI线程和工作线程。如果我们从工作线程中调用DoSomeStuff()
:
Invoke
第一个Dispatcher.Invoke(() => DoSomeStuff());
DoSomeOtherStuff();
将在UI线程上执行,然后DoSomeStuff()
将在工作线程上执行。如果是DoSomeOtherStuff()
:
InvokeAsync
我们只知道Dispatcher.InvokeAsync(() => DoSomeStuff());
DoSomeOtherStuff();
将在UI线程上执行,而DoSomeStuff()
将在工作线程上执行,但它们执行的顺序是不确定的。*
当您的委托产生一些结果并且需要它继续在工作线程上执行时(例如,当您需要获取依赖项属性值时),通常会使用DoSomeOtherStuff()
。另一方面,Invoke
通常在委托不产生任何结果(或结果被忽略)时使用,例如在你的情况下 - 更新InvokeAsync
不会产生任何值得等待的结果,所以你可以立即继续加载下一批数据。
我希望能为您解决这个问题,并且您可以看到为什么解决方案为&#34; jerky UI&#34;是将繁重的工作委托给另一个线程,只使用调度程序与UI进行交互。这是使用DataGrid
或BackgroundWorker
来自的建议。
*实际上它们可能会同时执行。我的意思是,如果两个方法只打印一些文本到控制台,控制台中的消息顺序是不确定的。