我刚刚重新访问了一些非常旧的代码,以将其更新为Prism的最新版本(版本5),并且在模块初始化期间,我收到以下异常消息:

Exception is: InvalidOperationException - To use the UIThread option for subscribing, the EventAggregator must be constructed on the UI thread.

无论我在哪里执行类似的操作:
eventAggregator.GetEvent<AppStatusMessageEvent>()
.Subscribe(OnAppStatusChanged, ThreadOption.UIThread, true);

将所有这些实例更改为:
eventAggregator.GetEvent<AppStatusMessageEvent>()
.Subscribe(OnAppStatusChanged);

显然可以解决该问题,并且该应用程序可以正常运行。

您如何确保Unity在UI线程上构造EventAggregator?

更新

我现在将以下代码添加到解决方案中,以解决此问题:
protected override void ConfigureContainer()
{
    Container.RegisterType<IShellView, Shell>();

    var eventAggregator = new EventAggregator();
    Container.RegisterInstance(typeof(IEventAggregator), eventAggregator);

    base.ConfigureContainer();
}

因此,这是在Bootstrapper的UI线程上显式创建EventAggregator,我仍然看到ThreadOption.UIThread引发了相同的异常。
StockTraderRI示例项目还利用了ThreadOption.UIThread,在处理IEventAggregator时似乎没有做任何明确的事情,但它使用的是MEF而不是Unity

我已经遍历了新的Prism版本5文档,并且在其中可以找到有关这些更改的所有内容,内容为:



我曾在上面详细介绍的代码更改中尝试过此操作。

我的Bootstrapper看起来与我可以找到的所有引用实现相同:
/// <summary>
/// Initializes the shell.
/// </summary>
protected override void InitializeShell()
{
    base.InitializeShell();

    Application.Current.MainWindow = (Shell)Shell;
    Application.Current.MainWindow.Show();
}

/// <summary>Creates the shell.</summary>
/// <returns>The main application shell</returns>
protected override DependencyObject CreateShell()
{
    return ServiceLocator.Current.GetInstance<Shell>();
}

我还尝试过在调用EventAggregator之后立即手动解决ConfigureContainer,如下所示:
/// <summary>Configures the container.</summary>
protected override void ConfigureContainer()
{
    base.ConfigureContainer();
    var ea = Container.Resolve<IEventAggregator>();
}

当查看syncContext上的ea属性时,它是否为null,尽管这似乎是UI线程上已解决的EventAggregator。而且我仍然看到这种异常。

有没有人看到这个问题,并找出导致这个问题的原因?

我完全陷入了困境。

另一个更新

所以我只是检查了要在哪个线程上创建。我从EventAggregator派生了一个空类,并将一个断点放在ctor上,构建该类的线程是Main Thread ...

所以现在我更加困惑了。

最佳答案

原来答案很简单。

在我的旧代码中,有一个看起来像这样的应用程序类是可以的(如果不理想的话):

public partial class App
{
    public App()
    {
        var bootstrapper = new MyBootStrapper();
        bootstrapper.Run();
    }
}

Prism 5不再适用于这种初始化。您需要像这样初始化应用程序:
public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        var bootStrapper = new MyBootStrapper();
        bootStrapper.Run();
    }
}

关于c# - Prism EventAggregator异常-必须在UI线程上构造,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31210687/

10-10 12:31