首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >棱镜EventAggregator异常-必须在UI线程上构造

棱镜EventAggregator异常-必须在UI线程上构造
EN

Stack Overflow用户
提问于 2015-07-03 16:01:14
回答 1查看 2.4K关注 0票数 1

我刚刚重新查看了一些非常老的代码,以便将其更新为最新版本的Prism (版本5),在模块初始化过程中,我得到了以下异常消息:

代码语言:javascript
复制
Exception is: InvalidOperationException - To use the UIThread option for subscribing, the EventAggregator must be constructed on the UI thread.

无论我在哪里执行这样的任务:

代码语言:javascript
复制
eventAggregator.GetEvent<AppStatusMessageEvent>()
.Subscribe(OnAppStatusChanged, ThreadOption.UIThread, true);

将所有这些实例更改为:

代码语言:javascript
复制
eventAggregator.GetEvent<AppStatusMessageEvent>()
.Subscribe(OnAppStatusChanged);

显然,修复了这个问题,并且应用程序正常运行。

如何确保统一在UI线程上构造EventAggregator?

更新

我现在已经将以下代码添加到解决方案中,试图解决这个问题:

代码语言:javascript
复制
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文档,在其中我能找到的关于这些更改的所有声明都是这样的:

现在必须在UI线程上构造EventAggregator,以正确获取对UI线程的SynchronizationContext的引用。

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

我的Bootstrapper看起来与我可以找到的所有参考实现相同:

代码语言:javascript
复制
/// <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,如下所示:

代码语言:javascript
复制
/// <summary>Configures the container.</summary>
protected override void ConfigureContainer()
{
    base.ConfigureContainer();
    var ea = Container.Resolve<IEventAggregator>();
}

当查看ea上的ea属性时,它是否是null,尽管它似乎是在UI线程上解析的EventAggregator。但我还是看到了这个例外。

有没有人看过这个问题,知道是什么引起了这个问题?

我完全不知所措。

另一个更新

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

所以现在我更困惑了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-05 22:40:42

结果发现答案很简单。

在我的旧代码中,如果有一个app类看起来如下所示(如果不是理想的话):

代码语言:javascript
复制
public partial class App
{
    public App()
    {
        var bootstrapper = new MyBootStrapper();
        bootstrapper.Run();
    }
}

棱镜5不再适用于这种初始化。您需要像这样初始化应用程序:

代码语言:javascript
复制
public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        var bootStrapper = new MyBootStrapper();
        bootStrapper.Run();
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31210687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档