经常使用多个线程更新UI控件

时间:2014-08-07 11:25:59

标签: wpf binding

我有一个DevExpress GridControl,它一直绑定到viewmodel中的tableview。大约有20个后台线程从数据库查询数据并单独更新tableview。对表视图的更新是带有锁定异步更新的守护程序。 Dispatcher用于刷新主UI线程。我还有另一个按钮来取消数据库并通过CancellationTokenSource更新功能。

然而,当应用程序运行时,我必须多次单击取消按钮才能在取消命令中执行代码。换句话说,UI主线程正忙于刷新GridControl并阻止取消按钮。

有没有办法实现这个功能?

编辑:发现此方法有很多帮助等待Dispatcher.Yield(DispatcherPriority.ApplicationIdle); 它只是让其他UI控件有机会被执行。

  

创建一个等待对象,该对象异步地将控制权交还给当前的调度程序,并为调度程序提供处理其他事件的机会。 (MSDN)

1 个答案:

答案 0 :(得分:0)

AFAIK,UI代表用户界面,主要部分是用户用户不是机器人,而是使用您的应用程序的人。您不需要在UI线程上经常查询数据更新。为什么数据库查询操作需要20个线程?你有一个GridControl,它可以在屏幕上只显示几行,20,50,100(不再)。因此,我建议您只有一个线程用于从数据库中读取数据,并且每2-5秒执行一次,以便为用户提供一些交互性。为此,TPL - 是不错的选择。与CancellationToken一起使用 - 是支持您的方案取消的好方法。在数据库查询之间,您可以执行以下操作:

while (true)
{
    myToken.ThrowIfCancellationRequested();
    // database query here

    myToken.WaitHandle.WaitOne(2000)
}

此外,在更新源集合之前,您可以使用以下内容:

GridControl.BeginDataUpdate();
//Update your source collection
GridControl.EndDataUpdate();

这会阻止DevExpress控件监听CollectionChanged事件或其他任何事件,因为在每个添加/删除操作DevExpress调用UpdateLayout()方法时,这并不是我们想要的那么快。

  

如果布局在任何方面都无效,UpdateLayout调用将重做整个布局。因此,您应该避免在元素树中的每次增量和次要更改后调用UpdateLayout。