gpt4 book ai didi

WinForms多线程数据绑定(bind)场景,最佳实践?

转载 作者:行者123 更新时间:2023-12-02 12:11:47 25 4
gpt4 key购买 nike

我目前正在设计/重新设计一个应用程序的数据绑定(bind)部分,该部分大量使用 winforms 数据绑定(bind)和来自后台线程的更新(每秒一次,超过 100 条记录)。

假设该应用程序是一个股票交易应用程序,其中后台线程监视数据更改并将其放入数据对象中。这些对象存储在BindingList<>中并实现INotifyPropertyChanged通过数据绑定(bind)将更改传播到 winforms 控件。此外,数据对象当前正在通过 WinformsSynchronizationContext.Send 编码更改。到 UI 线程。用户可以在 UI 中输入某些值,这意味着某些值可以从双方进行更改。并且用户值不应该被更新覆盖。

所以我想到了几个问题:

  • 是否有通用的设计指南如何做到这一点(数据绑定(bind)中的后台更新)?
  • 何时以及如何在 UI 线程上进行编码(marshal)?
  • 后台线程交互的最佳方式是什么绑定(bind)/数据对象?
  • 应该使用哪些类/接口(interface)? (绑定(bind)源,...)
  • ...

UI 并不真正知道有一个后台线程来更新控件,并且根据我对数据绑定(bind)场景的理解,UI 不应该知道数据来自哪里......您可以想到后台线程作为将数据推送到 UI 的东西,所以我不确定后台工作程序是否是我正在寻找的选项。

有时您希望在数据/业务对象的操作期间获得一些 UI 响应(例如,在重新计算期间设置背景)。在绑定(bind)到背景的状态属性上引发属性更改还不够,因为计算完成后控件会重新绘制?我的想法是 Hook propertychanged 事件并在控件上调用 .update() ...对此还有其他想法吗?

最佳答案

这是一个难题,因为大多数“解决方案”都会导致大量自定义代码和大量调用 BeginInvoke()System.ComponentModel.BackgroundWorker (它本身只是 BeginInvoke 的薄包装)。

过去,我还发现您很快希望延迟发送您的 INotifyPropertyChanged直到数据稳定为止。处理一个属性更改事件的代码通常需要读取其他属性。您还经常有一个控件,每当多个属性之一的状态发生更改时就需要重新绘制自身,并且您不希望该控件过于频繁地重新绘制自身。

首先,每个自定义 WinForms 控件都应该读取在 PropertyChanged 中绘制自身所需的所有数据。事件处理程序,因此当它是 WM_PAINT 时不需要锁定任何数据对象。 ( OnPaint ) 消息。控件在获取新数据时不应立即重新绘制自身;相反,它应该调用 Control.Invalidate() 。 Windows 将结合 WM_PAINT消息发送到尽可能少的请求中,并且仅在 UI 线程无事可做时才发送它们。这最大限度地减少了重绘次数和数据对象锁定的时间。 (无论如何,标准控件大多通过数据绑定(bind)来完成此操作)

数据对象需要记录更改发生的内容,然后一旦完成一组更改,“踢”UI 线程调用 SendChangeEvents然后调用 PropertyChanged 的方法所有已更改属性的事件处理程序(在 UI 线程上)。而SendChangeEvents()方法正在运行时,必须锁定数据对象以阻止后台线程更新它们。

可以通过调用BeginInvoke来“踢”UI线程。每当一组更新已从数据库中读取时。通常,最好使用计时器让 UI 线程轮询,因为 Windows 仅发送 WM_TIMER当 UI 消息队列为空时发送消息,从而使 UI 感觉响应更快。

还考虑根本不使用数据绑定(bind),并让 UI 在每次计时器触发时询问每个数据对象“发生了什么变化”。数据绑定(bind)总是看起来不错,但很快就会成为问题的一部分,而不是解决方案的一部分。

由于数据对象的锁定/解锁很痛苦,并且可能无法足够快地从数据库读取更新,因此您可能希望向 UI 线程传递数据对象的(虚拟)副本。使数据对象是持久的/不可变的,使得对数据对象的任何改变都返回新的数据对象而不是改变当前的数据对象可以实现这一点。

持久对象听起来很慢,但不一定如此,请参阅 thisthat寻求一些指导。另请参阅thisthat关于堆栈溢出。

另请查看retlang - Message-based concurrency in .NET 。它的消息批处理可能很有用。

(对于 WPF,我会在 UI 线程中设置一个 View 模型,然后由后台线程从多线程模型中“批量”更新。但是,WPF 在组合数据绑定(bind)方面要好得多事件然后 WinForms。)

关于WinForms多线程数据绑定(bind)场景,最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/602735/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com