UI 线程访问不受控制
我有一个 Session 对象来管理对象状态(类似于 nhibernate 会话)。此会话侦听来自外部源的事件,这些事件可能需要更新内部会话状态。我们尝试在会话中实现锁定以确保访问的数据是一致的,但存在许多棘手的边缘情况。
相反,将这些事件编组到与使用会话(即 UI 线程)相同的线程上可能会更容易。通常,这是通过 Control.Invoke()
完成的,但因为这是一个数据对象,所以没有 Control
可以访问。
这是一种合理的方法吗?在更新会话状态之前,我该如何将此事件获取到 UI 线程上?我可以在创建会话时使用 Dispatcher
并捕获当前线程的调度程序吗?
I have a Session
object that manages object states (similar to a nhibernate session). This session listens to events from an external source that may require updates to the internal session state. We've tried implementing locking in the session to ensure the data accessed is coherent but there's so many fiddly edge cases.
Instead it might be easier to marshal these events onto the same thread as is using the session (which is the UI thread). Generally this is done with Control.Invoke()
but because this is a data object there is no Control
to access.
Is this a reasonable approach and how can I go about getting this events onto the UI thread before they update the session state? Can I use the Dispatcher
and capture the current thread's dispatcher when the session is created?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会让业务对象触发一个由视图 ( UI ) 捕获的事件,并对该事件处理程序进行封送,因此您在该位置有一个
Control
来了解是否需要调用或不是:如果您使用 WPF,您可以从 CaliburnMicro 中获取灵感:
I would let the business object fire an event to be caught by the view ( UI ) and do the marshaling on that event handler, so you have in that place a
Control
to understand if an invoke is needed or not:if you are using WPF, you can take inspiration from CaliburnMicro:
我认为锁定通常非常简单,它可能是您的最佳选择。正确地实现你想要的东西可能会更加困难(当然不是没有“复杂的边缘情况”)。
您可以做的是使用
BlockingCollection
并在单线程中从中出列。不幸的是,该线程将被阻塞,因此您无法使用 UI 线程。
I think that locking is usually pretty straight-forward and it may be your best option. Implementing what you want correctly would probably be much more difficult (and certainly not without “fiddly edge cases”).
What you could do though is use existing implementation of
BlockingCollection<T>
from .Net 4 and dequeue from it in single thread. Unfortunately, that thread would be blocked, so you can't use the UI thread.