[英]SynchronizationContext.Current is null on resolving with Unity in WPF
I have a WPF Code which looks something like this. 我有一个看起来像这样的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; }
}}
I use Unity to Resolve the above AlphaProductesVM
. 我使用Unity来解析上面的
AlphaProductesVM
。 This is instant when the Module is discovered using PRISM and the UnityBootstrapper. 使用PRISM和UnityBootstrapper发现模块时,这是即时的。 At runtime
.ObserveOn(SynchronizationContext.Current)
throws an exception and SynchronizationContext.Current
has a null
value in it. 在运行时
.ObserveOn(SynchronizationContext.Current)
抛出异常, SynchronizationContext.Current
中包含null
值。
The SynchronizationContext.Current property will only return a value when invoked on the main thread . SynchronizationContext.Current属性仅在主线程上调用时返回值 。
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 . 如果需要在主线程以外的线程中使用SynchronizationContext对象,则可以将与主线程关联的SynchronizationContext实例传递给需要它作为依赖项的类 。
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. 如果选择此解决方案,则可以将从主线程上的SynchronizationContext.Current属性获取的SynchronizationContext对象注册为容器中的单例 。 That way all requests for a SynchronizationContext from that point on will automatically be satisfied by the container with the singleton:
这样,具有单例的容器将自动满足从该点开始的所有SynchronizationContext请求:
// Must run in the main thread
container.RegisterInstance(SynchronizationContext.Current);
Although there is an implementation of SynchronizationContext
for WPF it is not recommended for use. 虽然有一个针对WPF的
SynchronizationContext
实现,但不建议使用它。 WPF has the Dispatcher
to build responsive applications . WPF具有
Dispatcher
来构建响应式应用程序 。
In addition SynchronizationContext.Current
only has a value if you are on the UI thread. 此外,如果您位于UI线程上,则
SynchronizationContext.Current
只有一个值。 If your logic runs in a background thread Current
will always be null. 如果您的逻辑在后台线程中运行,则
Current
将始终为null。
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.
然后从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;
}
}
or, if you inject the UI thread's dispatcher into your view model you can subscribe on that in the constructor. 或者,如果将UI线程的调度程序注入到视图模型中,则可以在构造函数中对其进行订阅。
var repository = new NorthwindRepository();
repository
.GetAllProducts()
.ObserveOn(theUIdispatcher)
.Subscribe(AddElement);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.