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

本文关键字:SynchronizationContext Current null WPF Unity | 更新日期: 2023-09-27 18:25:21

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

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

    public ObservableCollection<Alphabetical_list_of_product> NwCustomers
    {
        get { return _NwCustomers; }
        set { _NwCustomers = value; }
    }}

我使用Unity来解决上述AlphaProductesVM。当使用PRISM和UnityBootstrapper发现模块时,这是即时的。在运行时,.ObserveOn(SynchronizationContext.Current)抛出一个异常,而SynchronizationContext.Current中有一个null值。

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

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

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

如果选择此解决方案,则可以将从主线程上的SynchronizationContext.Current属性获得的Synchronization Context对象注册为容器中的singleton。这样,从那时起,所有对SynchronizationContext的请求都将自动由具有singleton的容器来满足:

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

尽管有针对WPF的SynchronizationContext实现,但不建议使用。WPF具有Dispatcher来构建响应型应用程序。

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

我不确定这是否会是一个流行的建议,但你可以懒洋洋地创建和订阅你的收藏。然后,从UI线程对NwCustomers的第一次访问将正确启动一切。

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

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

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