C# 应在UI线程上运行任何值时的反应UI
我在反应性松弛通道中问了这个问题,但我决定在这里也这样做。 我有一个UWP项目使用反应式UI(10,5,7)。我不是实际版本,但我可以工作,我不想升级。这种例外情况很少发生 但在我添加了一些功能之后,我会更频繁地使用它们。我总是在RxApp.MainThreadScheduler中引发PropertyChanged事件(我检查了好几次),但有时会触发异常。经过调查,我想我找到了一个原因:订阅/取消订阅PropertyChanged/PropertyChanged并引发这些事件必须在同一个线程中完成(查看WeakEventManager源代码,WeakHandlerList不是线程安全的)。我在文件中没有解释。为什么?我总是在UI线程中引发这些事件,但在非UI线程中执行VMs=>subscription/unsubscription之间的交互时,经常使用任何值方法。 例如:C# 应在UI线程上运行任何值时的反应UI,c#,multithreading,reactiveui,dynamic-data,C#,Multithreading,Reactiveui,Dynamic Data,我在反应性松弛通道中问了这个问题,但我决定在这里也这样做。 我有一个UWP项目使用反应式UI(10,5,7)。我不是实际版本,但我可以工作,我不想升级。这种例外情况很少发生 但在我添加了一些功能之后,我会更频繁地使用它们。我总是在RxApp.MainThreadScheduler中引发PropertyChanged事件(我检查了好几次),但有时会触发异常。经过调查,我想我找到了一个原因:订阅/取消订阅PropertyChanged/PropertyChanged并引发这些事件必须在同一个线程中完
public class ViewModelA : ReactiveObject
{
[Reactive] public int PropA { get; set; }
}
public class ViewModelB : ReactiveObject
{
private ViewModelA _vmA;
public int PropB { [ObservableAsProperty]get; }
public ViewModelB()
{
_vmA = new ViewModelA();
_vmA.WhenAnyValue(x => x.PropA) // subscription will be performed in current thread
.Select(val => val + 10)
.ToPropertyEx(this, vm => vm.PropB, 0, false, RxApp.MainThreadScheduler);
}
}
如果将从视图(UI线程)设置PropA,则将在ViewModelB创建线程中执行PropA更改的订阅和取消订阅。
因此,WeakHandlerList中的_handlers字段可以从不同的线程中更改,这是不能更改的。
因此,我必须始终在我的虚拟机中的任何值之后添加SubscribeOn(RxApp.MainThreadScheduler),并始终将RxApp.MainThreadScheduler传递给TopPropertyEx,即使在UI线程中也不会观察到该属性
同样的问题也存在于ObservalElistex.AutoRefresh中,ObservalElistex.WhenAnyPropertyChanged中。这些方法也必须订阅UI线程中的PropertyChanged。所以我应该这样称呼他们
list.Connect()
.ObserveOn(RxApp.MainThreadScheduler)
.AutoRefresh(x => x.Prop)
.ObserveOn(Scheduler.Default)
other methods
.Subscribe()
但也许我错了