2016-12-05 1 views
1

서로를 부정하는 2 개의 확인란을 설정했습니다. RxUI에서 순환 참조 감지

I 볼 생각 동작이

RxUI 의해 확인되는 infintite 루프 (체크 박스를 체크 한 2 체크 한 체크 2 ...) 대신 변화의 전파가 다른 다른 체크 박스 후에 정지

이었다.

순환 참조가 RxUI로 빌드 된 것이 있습니까?

using ReactiveUI; 
using ReactiveUI.Fody.Helpers; 
using System; 

namespace rxnested 
{ 
    public class VM01 : ReactiveObject 
    { 
     [Reactive] 
     public bool Prop1 { get; set; } 

     [Reactive] 
     public bool Prop2 { get; set; } 

     public VM01() 
     { 
      this.WhenAnyValue(x => x.Prop1) 
       .Subscribe(x => Prop2 = !x); 


      this.WhenAnyValue(x => x.Prop2) 
       .Subscribe(x => Prop1 = !x); 
     } 
    } 
} 

<Window x:Class="rxnested.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:rxnested" 
     mc:Ignorable="d" 
     Title="MainWindow" 
     Height="350" 
     Width="525"> 
    <Window.DataContext> 
     <local:VM01></local:VM01> 
    </Window.DataContext> 
    <StackPanel> 
     <CheckBox IsChecked="{Binding Prop1}"></CheckBox> 
     <CheckBox IsChecked="{Binding Prop2}"></CheckBox> 
    </StackPanel> 
</Window> 
+0

나는 희망하지 않으며 의심 스럽다. IMO를 사용하면 프레임 워크가 느려집니다. 이 경우에는 다른 종류의 무한 루프를 작성하지 않는 것이 프로그래머의 임무입니다. – kenny

답변

2

여러분의 코드가 무한 루프를 초래해야한다는 귀하의 기대가 잘못되었다고 생각합니다.

두 가지 시나리오가 있습니다. 별도로 고려해 보겠습니다.

1) 처음에는 두 속성이 모두 같은 값을 가지고 있다고 가정 해 봅시다 (false라고 가정 해 봅시다). P1을 true로 변경하면 P1의 현재 값의 역순으로 P2를 설정하려고하는 첫 번째 구독이 트리거됩니다 (true == false와 반대). 즉, 이미 false였던 것을 false로 설정하려고 시도하므로 아무 것도 발생하지 않습니다 (즉, [Reactive] - 속성을 설정하기 전에 변경된 사항이 있는지 확인합니다).

2) 이제 P1은 처음에는 참이고 P2는 거짓입니다. P1을 false로 변경하면 P2를 (! P1)로 설정하는 첫 번째 구독이 트리거됩니다.이 경우는 참입니다. 따라서 P2는 거짓에서 참으로 바뀝니다. 그러면 두 번째 구독이 시작되어 P1을 (! P2)로 설정하려고 시도합니다. 이는 현재 false입니다. 그러나 P1은 이미 거짓이므로 속성이 변경되지 않으므로 NotifyPropertyChanged가 실행되지 않습니다.

그래서 속성을 맹목적으로 설정하지 않고 처음 변경되었는지 (불필요한 NotifyPropertyChanged 이벤트를 피하기 위해) 변경되었는지에 따라주기가 깨집니다. 당신이 [Reactive]가로 변환 실현 될 때

이 더욱 분명하다

private bool _prop2; 
    public bool Prop2 
    { 
     get { return _prop2; } 
     set { this.RaiseAndSetIfChanged(ref _prop2, value); } 
    } 

주의 이름을 - RaiseAndSet 을 IfChanged.

이제, 당신은 단순히 이것으로 코드를 변경 .. 무한 루프를보고 싶다면이 나에게 StackOverflowException을 제공

public VM01() 
    { 
     this.WhenAnyValue(x => x.Prop1) 
      .Subscribe(x => Prop2 = !Prop2); 


     this.WhenAnyValue(x => x.Prop2) 
      .Subscribe(x => Prop1 = !Prop1); 
    } 

.