在WPF中使用Unity解析时,SynchronizationContext.Current为null

我有一个看起来像这样的WPF代码。

public class AlphaProductesVM : BaseModel { private ObservableCollection _NwCustomers; private int i = 0; public AlphaProductesVM () { _NwCustomers = new ObservableCollection(); var repository = new NorthwindRepository(); repository .GetAllProducts() .ObserveOn(SynchronizationContext.Current) .Subscribe(AddElement); } public void AddElements(IEnumerable elements) { foreach (var alphabeticalListOfProduct in elements) { AddElement(alphabeticalListOfProduct); } } public ObservableCollection NwCustomers { get { return _NwCustomers; } set { _NwCustomers = value; } }} 

我使用Unity来解析上面的AlphaProductesVM 。 使用PRISM和UnityBootstrapper发现模块时,这是即时的。 在运行时.ObserveOn(SynchronizationContext.Current)抛出exception, SynchronizationContext.Current中包含null值。

SynchronizationContext.Current属性仅在主线程上调用时返回一个值

如果需要在主线程以外的线程中使用SynchronizationContext对象,则可以将与主线程关联的SynchronizationContext实例传递给需要它作为依赖关系的类

如果选择此解决方案,则可以将从主线程上的SynchronizationContext.Current属性获取的SynchronizationContext对象注册为容器中的单例 。 这样,具有单例的容器将自动满足从该点开始的所有SynchronizationContext请求:

 // Must run in the main thread container.RegisterInstance(SynchronizationContext.Current); 

虽然有一个针对WPF的SynchronizationContext实现,但不建议使用它。 WPF具有Dispatcher来构建响应式应用程序 。

此外,如果您位于UI线程上,则SynchronizationContext.Current只有一个值。 如果您的逻辑在后台线程中运行,则Current将始终为null。

我不确定这是否是一个受欢迎的建议,但你可以懒洋洋地创建和订阅你的collections。 然后,从UI线程第一次访问NwCustomers将正确地解决所有问题。

 public AlphaProductesVM (){} public ObservableCollection NwCustomers { get { if(_NwCustomers == null) { _NwCustomers = new ObservableCollection(); var repository = new NorthwindRepository(); repository .GetAllProducts() .ObserveOn(SynchronizationContext.Current) .Subscribe(AddElement); } return _NwCustomers; } } 

或者,如果您将UI线程的调度程序注入到视图模型中,则可以在构造函数中对其进行订阅。

  var repository = new NorthwindRepository(); repository .GetAllProducts() .ObserveOn(theUIdispatcher) .Subscribe(AddElement);