【问题标题】:Firing an Event from a Timer to WPF UI将事件从计时器触发到 WPF UI
【发布时间】:2010-06-04 21:54:28
【问题描述】:

我有一个应用程序,它由一个 WPF UI 组成,它下面有一个“基础设施”层,其中有一些对各种数据服务的引用。我有一个类,Updater,它有几个属性代表 UI 层要使用的数据。此更新程序有一个 Systems.Timer 功能,因此每隔一分钟左右,它就会对服务进行同步调用,并通过“刷新”数据来更新上述属性。

我想从这个类中引发一个事件,当它完成时,UI 可以收到更改通知。当我之前做类似的事情时,它会左右抛出异常,因为触发事件的线程不同(因为它来自计时器经过的事件)然后是创建对象的线程。

我现在使用的糟糕解决方案是在 UI 层上设置另一个计时器,但是......糟糕。

通知 UI Updater 类已完成所有工作的最佳方式是什么?

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    那些跨线程异常可以通过Dispatcher.Invoke函数更新UI来解决。 Dispatcher 是一个可用于调用 UI 线程的对象。仔细阅读this article,你应该准备好了。

    【讨论】:

    • @Perplexed:查理的回答很好(+1)。一个警告:忽略链接文章的最后三段,因为它包含不准确的信息:您通常不应该使用 CheckAccess。在 StackOverflow 上的其他地方搜索我的答案以了解详细信息。否则那篇文章是一个很好的资源。
    • 我以为我试过了,但它死得很惨。明天会试试这个,并在应得的地方给予奖励。
    • 我想我得到了这个工作 - 我不知道为什么它第一次对我不起作用,但我很确定我没有正确使用它。我从基础设施层的 TimerElapsed 函数触发了一个事件,它由 UI 层处理。 UI 上的函数调用封装在 Dispatcher.Invoke() 中。
    【解决方案2】:

    如果可以的话,最好的方法是通过绑定。使用您的数据类实现System.ComponentModel.INotifyPropertyChanged 接口,然后将您的 UI 元素绑定到您要显示的这些类的属性。更新属性时,它们会触发 PropertyChanged 事件,该事件由 WPF 依赖对象在内部处理并自动更新您的 UI。这是一种避免您通常必须自己组装以响应更新的大量管道的方法。

    This 博客条目提供了一个很好的示例来说明如何使用它,但网上还有更多可用的示例。

    【讨论】:

    • 如果您从非 Ui 线程设置属性,这仍然会引发异常。
    • 这可能是一个很好的方法,但我们正在寻找更多的快速和肮脏的方式。
    • Rusty 的评论是正确的;虽然这是更新绑定属性的好方法,但它不会防止跨线程异常。
    • @Rusty, @Charlie 这是一个通过绑定从异步操作中影响 UI 更新的示例。我错过了什么吗? mediafire.com/?0nmjzu3o2cz
    • @Rusty 你能再解释一下吗?我的示例清楚地显示了通过异步调用进行的 UI 更新,而无需编组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多