2

我正在尝试在后台任务运行时更新主窗体中的进度条。

我正在使用来自最新模式和实践发布的 EventAggregator 路由我的应用程序范围的事件。

我正在从一个监听 BackgroundWorker 事件的类中触发一个事件,然后像这样触发一个事件:

  1. BW 上的进程触发 BW 方法以报告进度。
  2. BW 触发它的报告事件。
  3. 它们被在 BW 启动之前设置的 SomeCommand 类方法拾取。
  4. 我从 EventAggregator 发布事件

public void ProgressChanged(对象发送者,ProgressChangedEventArgs ea){ KnownProgressStatusChangedEvent evt = KernelKeeper.Kernel.Get().GetEvent(); evt.Publish(ea); }

我的 MainPresenter 已经订阅了这些事件:

    KnownProgressStatusChangedEvent progressChanged = EventAggregator.GetEvent<KnownProgressStatusChangedEvent>();
    progressChanged.Subscribe(KnownProgressChanged,ThreadOption.UIThread);

如果我不设置 ThreadOption.UIThread,我会在 Program.cs 中得到 TargetInvokationException,并且没有堆栈跟踪。这样我就没有例外,我可以进入 EventAggregator。

当它即将调用 KnownProgressChanged 方法时,它会尝试调用它并检查Application.Current != null. 它是空的,没有任何东西被解雇。

我究竟做错了什么 ?请指教。

4

2 回答 2

2

您必须指定 ThreadOption.UIThread 因为您正在处理进度条,必须从 ui 线程调用处理程序才能绘制新的进度状态。

但是,如果您正在使用 WPF,则必须在没有 ThreadOption.UIThread 和自己调度调用,您可以查看 CompositeWpfEvent。

事件聚合器- 在用户界面线程上订阅

订阅者经常需要更新用户界面元素以响应事件。在 Windows Presentation Foundation (WPF) 中,只有 UI 线程可以更新用户界面元素。默认情况下,订阅者在发布者线程上接收事件,因此如果发布者从 UI 线程发送事件,订阅者将能够更新用户界面。

但是,如果发布者的线程是后台线程,订阅者可能无法直接更新用户界面元素。相反,它需要使用 Windows Presentation Foundation 的 Dispatcher 类在 UI 线程上安排更新。复合应用程序库提供的 CompositeWpfEvent 可以通过允许订阅者自动接收 UI 线程上的事件来提供帮助。订阅者必须在订阅过程中指出这一点,如以下代码所示。

...

于 2009-11-19T17:05:06.347 回答
1

TargetInvocationException 是一个红鲱鱼,我是由于在我的代码中的其他地方抛出了一个未实现的异常而引起的。

我正在使用 WinForms 并将订阅与 ThreadOption.PublisherThread 选项一起使用,并且效果很好。

于 2009-11-23T16:13:02.983 回答