SynchronizationContext.Current is null to resolve with Unity in WPF

I have a WPF code that 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 the instant that a module is detected using PRISM and UnityBootstrapper. At runtime, .ObserveOn(SynchronizationContext.Current) throws an exception, and SynchronizationContext.Current is null .

+4
source share
3 answers

The SynchronizationContext.Current property will return a value only when called in the main thread .

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

If you choose this solution, you can register the SynchronizationContext object obtained from SynchronizationContext.Current in the main stream as a single element in your container. Thus, all requests for the SynchronizationContext from this point will be automatically executed by the container with singleton:

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

Although there is a SynchronizationContext implementation for WPF, it is not recommended. WPF has Dispatcher to create responsive applications .

In addition, SynchronizationContext.Current is only relevant if you are in the user interface thread. If your logic runs in the Current background thread, it will always be null.

0
source

I'm not sure this will be a popular offer, but you can lazily create and subscribe to your collection. Then the first access to NwCustomers from the UI thread will completely remove everything.

 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 introduce a UI thread manager into your view model, you can subscribe to it in the constructor.

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

Source: https://habr.com/ru/post/908914/


All Articles