我有一个看起来像这样的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
值。
答案 0 :(得分:4)
SynchronizationContext.Current属性只会在主线程上调用时返回一个值。
如果您需要在主线程以外的线程中使用SynchronizationContext对象,则可以将与主线程关联的SynchronizationContext实例传递给需要的类作为依赖。
如果您选择此解决方案,则可以将主线程上从SynchronizationContext属性获取的SynchronizationContext.Current对象注册为 singleton 你的容器。这样,具有单身的容器将自动满足从该点开始的SynchronizationContext的所有请求:
// Must run in the main thread
container.RegisterInstance(SynchronizationContext.Current);
答案 1 :(得分:0)
尽管WPF实现了SynchronizationContext
,但建议不要使用它。 WPF有Dispatcher
到build responsive applications。
此外,如果您在UI线程上,SynchronizationContext.Current
只有一个值。如果您的逻辑在后台运行,则Current
将始终为空。
答案 2 :(得分:0)
我不确定这是否是一个受欢迎的建议,但您可以懒洋洋地创建和订阅您的收藏。然后,从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);