SynchronizationContext.Current is null on resolving with Unity in WPF

爷,独闯天下 提交于 2019-11-30 05:21:38

问题


I have a WPF Code which looks something like this.

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; }
    }}

I use Unity to Resolve the above AlphaProductesVM. This is instant when the Module is discovered using PRISM and the UnityBootstrapper. At runtime .ObserveOn(SynchronizationContext.Current) throws an exception and SynchronizationContext.Current has a null value in it.


回答1:


The SynchronizationContext.Current property will only return a value when invoked on the main thread.

If you need to use a SynchronizationContext object in threads other than the main thread, you could pass the SynchronizationContext instance associated to the main thread to the classes that need it as a dependency.

If you choose this solution, you could register the SynchronizationContext object obtained from the SynchronizationContext.Current property on the main thread as a singleton in your container. That way all requests for a SynchronizationContext from that point on will automatically be satisfied by the container with the singleton:

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



回答2:


Although there is an implementation of SynchronizationContextfor WPF it is not recommended for use. WPF has the Dispatcher to build responsive applications.

In addition SynchronizationContext.Current only has a value if you are on the UI thread. If your logic runs in a background thread Current will always be null.




回答3:


I'm not sure if this will be a popular suggestion, but you could lazily create and subscribe to your collection. Then the first access to NwCustomers from the UI thread will kick everything off correctly.

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; 
    }
}

or, if you inject the UI thread's dispatcher into your view model you can subscribe on that in the constructor.

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


来源:https://stackoverflow.com/questions/9377290/synchronizationcontext-current-is-null-on-resolving-with-unity-in-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!