我有一个DevExpress GridControl,它一直绑定到viewmodel中的tableview。大约有20个后台线程从数据库查询数据并单独更新tableview。对表视图的更新是带有锁定异步更新的守护程序。 Dispatcher用于刷新主UI线程。我还有另一个按钮来取消数据库并通过CancellationTokenSource更新功能。
然而,当应用程序运行时,我必须多次单击取消按钮才能在取消命令中执行代码。换句话说,UI主线程正忙于刷新GridControl并阻止取消按钮。
有没有办法实现这个功能?
编辑:发现此方法有很多帮助等待Dispatcher.Yield(DispatcherPriority.ApplicationIdle); 它只是让其他UI控件有机会被执行。
创建一个等待对象,该对象异步地将控制权交还给当前的调度程序,并为调度程序提供处理其他事件的机会。 (MSDN)
答案 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。