Prism EventAggregator 异常 - 必须在 UI 线程上构造
Prism EventAggregator Exception - must be constructed on the UI thread
我刚刚重新访问了一些非常旧的代码,将其更新为最新版本的 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
.[=34= 抛出相同的异常]
StockTraderRI
示例项目也使用了 ThreadOption.UIThread
,并且在处理 IEventAggregator
时似乎没有做任何明确的事情,但它正在使用 MEF
不是 Unity
.
我已经阅读了新的 Prism 版本 5 文档,我能在其中找到关于这些更改的所有声明:
EventAggregator now must be constructed on the UI thread to properly
acquire a reference to the UI thread’s SynchronizationContext.
我在上面详述的代码更改中尝试过。
我的 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>();
}
我还尝试在调用 ConfigureContainer
后立即手动解析 EventAggregator
,如下所示:
/// <summary>Configures the container.</summary>
protected override void ConfigureContainer()
{
base.ConfigureContainer();
var ea = Container.Resolve<IEventAggregator>();
}
当查看 ea
上的 syncContext
属性 是 null
尽管 EventAggregator
似乎已在 UI线程。而且我仍然看到这个异常。
有没有人看到这个问题并找出导致这个问题的原因?
我完全被难住了。
另一个更新
所以我刚刚检查了这是在哪个线程上创建的。我从 EventAggregator
派生了一个空 class 并在 ctor
上放置了一个断点,构建 class 的线程是 Main Thread
...
所以现在我更糊涂了
原来答案很简单。
在我的旧代码中,有一个看起来像这样的应用程序 class 是可以的(如果不理想的话):
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();
}
}
我刚刚重新访问了一些非常旧的代码,将其更新为最新版本的 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
.[=34= 抛出相同的异常]
StockTraderRI
示例项目也使用了 ThreadOption.UIThread
,并且在处理 IEventAggregator
时似乎没有做任何明确的事情,但它正在使用 MEF
不是 Unity
.
我已经阅读了新的 Prism 版本 5 文档,我能在其中找到关于这些更改的所有声明:
EventAggregator now must be constructed on the UI thread to properly acquire a reference to the UI thread’s SynchronizationContext.
我在上面详述的代码更改中尝试过。
我的 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>();
}
我还尝试在调用 ConfigureContainer
后立即手动解析 EventAggregator
,如下所示:
/// <summary>Configures the container.</summary>
protected override void ConfigureContainer()
{
base.ConfigureContainer();
var ea = Container.Resolve<IEventAggregator>();
}
当查看 ea
上的 syncContext
属性 是 null
尽管 EventAggregator
似乎已在 UI线程。而且我仍然看到这个异常。
有没有人看到这个问题并找出导致这个问题的原因?
我完全被难住了。
另一个更新
所以我刚刚检查了这是在哪个线程上创建的。我从 EventAggregator
派生了一个空 class 并在 ctor
上放置了一个断点,构建 class 的线程是 Main Thread
...
所以现在我更糊涂了
原来答案很简单。
在我的旧代码中,有一个看起来像这样的应用程序 class 是可以的(如果不理想的话):
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();
}
}