WinForms多线程数据绑定场景,最佳做法?
我正在设计/重新编写一个应用程序的数据绑定部分,这些部分大量使用
winforms数据绑定和更新来自后台线程(在> 100个记录上一次).
假设应用程序是股票交易应用程序,后台线程监视数据更改并将其放在数据对象上.这些对象存储在绑定列表<>并实现INotifyPropertyChanged通过数据绑定将更改传播到winforms控件. 此外,数据对象当前正在通过 WinformsSynchronizationContext.Send将更改编组到UI线程. 用户能够在UI中输入一些值,这意味着可以从两面更改一些值.用户值不应该被更新覆盖. 所以我想到了几个问题: >有没有一般的设计公民如何做(数据绑定的后台更新)? 我正在搜索这种情景的一般建议/设计指南… 我感谢所有的想法,链接,… TIA thx的想法到目前为止,但我知道Control.Invoke / BeginInvoke,…我更好地在最佳实践.作为一个附加信息,UI并不知道有一个后台线程,更新控件,并且根据我在数据绑定场景中的理解,UI不应该知道数据来自哪里…你可以认为的背景线程作为将数据推送到UI的东西,所以我不知道backgroundworker是否是我正在搜索的选项. 编辑: 解决方法
这是一个困难的问题,因为大多数“解决方案”导致大量的自定义代码和大量的调用BeginInvoke()或System.ComponentModel.BackgroundWorker(它本身只是一个薄的封装在BeginInvoke上).
过去,我也发现您很快希望延迟发送INotifyPropertyChanged事件,直到数据稳定.处理一个改变事件的代码通常需要阅读其他特性.当许多属性之一的状态发生变化时,您也经常有一个需要重新绘制的控件,而且您也不需要太多频繁地重新绘制控件. 首先,每个自定义WinForms控件都应该读取所??有需要在PropertyChanged事件处理程序中绘制的数据,因此当它是一个WM_PAINT(OnPaint)消息时,它不需要锁定任何数据对象.控制器在获取新数据时不应立即重绘;而应该调用Control.Invalidate(). Windows会将WM_PAINT消息组合到尽可能少的请求中,并且只有当UI线程没有其他任何事情时才发送它们.这样可以最大限度地减少重绘次数和数据对象被锁定的时间. (标准控件大多是通过数据绑定来实现的) 数据对象需要记录改变的内容,然后一旦完成了一组更改,“踢”UI线程调用SendChangeEvents方法,然后调用PropertyChanged事件处理程序(在UI线程上)所有属性已更改. SendChangeEvents()方法正在运行时,必须锁定数据对象以阻止后台线程进行更新. 每当一组更新从数据库读取bean时,UI线程可以通过对BeginInvoke的调用“踢”.通常最好使用定时器进行UI线程轮询,因为Windows在UI消息队列为空时才发送WM_TIMER消息,因此导致UI感觉更加敏感. 还要考虑到根本不使用数据绑定,并且每当定时器触发时,UI都要求每个数据对象“发生什么变化”.数据绑定总是看起来不错,但可以很快成为问题的一部分,而不是部分解决方案. 因为数据对象的锁定/解锁是一种痛苦,并且可能不允许从数据库中读取更新的速度足够快,您可能希望将UI线程传递给数据对象的(虚拟)副本.使数据对象持久/不可变,以便对数据对象的任何更改返回一个新的数据对象,而不是更改当前数据对象可以启用此功能. 持久的对象听起来很慢,但不一定要看一些指针this和that.另请参阅堆栈溢出上的this和that. 还可以看看retlang – Message-based concurrency in .NET.它的消息批处理可能很有用. (对于WPF,我将有一个View-Model,它设置在UI线程中,然后通过后台线程从多线程模型的“批处理”中更新,然而WPF在组合数据绑定事件WinForms .) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |