Subject<T> 형식은 관찰자이자 관찰 가능한 형식이라는 점에서 IObservable<T> 와 IObserver<T>를 모두 구현합니다. 주체를 사용하여 모든 관찰자를 구독한 다음, 주체를 백 엔드 데이터 원본에 구독할 수 있습니다. 이러한 방식으로 주체는 구독자 그룹 및 원본에 대한 프록시 역할을 할 수 있습니다. 주체를 사용하여 캐싱, 버퍼링 및 시간 이동을 통해 관찰 가능한 사용자 지정을 구현할 수 있습니다. 또한 주체를 사용하여 여러 구독자에게 데이터를 브로드캐스트할 수 있습니다.
기본적으로 주체는 스레드 간에 동기화를 수행하지 않습니다. 스케줄러를 사용하는 것이 아니라 모든 직렬화 및 문법 정확성이 주체의 호출자에 의해 처리된다고 가정합니다. 주체는 스레드로부터 안전한 구독자 목록의 모든 구독된 관찰자에게 브로드캐스트하기만 합니다. 이렇게 하면 오버헤드를 줄이고 성능을 향상시킬 수 있는 이점이 있습니다. 그러나 스케줄러를 사용하여 관찰자에게 나가는 호출을 동기화하려는 경우 Synchronize 메서드를 사용하여 이 작업을 수행할 수 있습니다.
주제 사용
다음 예제에서는 제목을 만들고 해당 제목을 구독한 다음 동일한 제목을 사용하여 관찰자에게 값을 게시합니다. 이렇게 하면 게시와 구독을 동일한 원본으로 결합합니다.
IObserver<T>를 사용하는 것 외에도 Subscribe 메서드에는 onNext에 대해 Action<T> 를 사용하는 오버로드가 있습니다. 즉, 항목이 게시될 때마다 작업이 실행됩니다. 이 샘플에서는 OnNext가 호출될 때마다 항목이 콘솔에 기록됩니다.
Subject<int> subject = new Subject<int>();
var subscription = subject.Subscribe(
x => Console.WriteLine("Value published: {0}", x),
() => Console.WriteLine("Sequence Completed."));
subject.OnNext(1);
subject.OnNext(2);
Console.WriteLine("Press any key to continue");
Console.ReadKey();
subject.OnCompleted();
subscription.Dispose();
다음 예제에서는 주체의 프록시 및 브로드캐스트 특성을 보여 줍니다. 먼저 1초마다 정수 생성 소스 시퀀스를 만듭니다. 그런 다음, Subject를 만들고 이 소스 시퀀스에서 푸시된 모든 값을 받을 수 있도록 관찰자로 원본에 전달합니다. 그런 다음 이번에는 주체를 원본으로 사용하여 또 다른 두 개의 구독을 만듭니다. 그런 다음 및 subSubject2 구독은 subSubject1 주체에 의해 전달된 값(원본에서)을 받습니다.
var source = Observable.Interval(TimeSpan.FromSeconds(1));
Subject<long> subject = new Subject<long>();
var subSource = source.Subscribe(subject);
var subSubject1 = subject.Subscribe(
x => Console.WriteLine("Value published to observer #1: {0}", x),
() => Console.WriteLine("Sequence Completed."));
var subSubject2 = subject.Subscribe(
x => Console.WriteLine("Value published to observer #2: {0}", x),
() => Console.WriteLine("Sequence Completed."));
Console.WriteLine("Press any key to continue");
Console.ReadKey();
subject.OnCompleted();
subSubject1.Dispose();
subSubject2.Dispose();
다양한 유형의 주체
Rx 라이브러리의 Subject<T> 형식은 ISubject T 인터페이스의 기본 구현입니다(ISubject<<T>> 인터페이스를 구현하여 사용자 고유의 제목 형식을 만들 수도 있음). 다른 기능을 제공하는 ISubject<T> 의 다른 구현이 있습니다. 이러한 모든 형식은 OnNext를 통해 푸시된 일부(또는 전체) 값을 저장하고 해당 관찰자에게 다시 브로드캐스트합니다. 이러한 방식으로 핫 관찰 가능을 콜드로 변환합니다. 즉, 이러한 값 중 하나를 두 번 이상 구독하는 경우(예: 구독 취소 ->> 다시 구독) 동일한 값 중 하나 이상이 다시 표시됩니다. 핫 및 콜드 관찰 가능 개체에 대한 자세한 내용은 단순 관찰 가능한 시퀀스 만들기 및 구독 항목의 마지막 섹션을 참조하세요.
ReplaySubject는 게시된 모든 값을 저장합니다. 따라서 구독하면 특정 값이 푸시된 후 구독이 들어왔을 수 있더라도 게시된 값의 전체 기록을 자동으로 받게 됩니다. BehaviourSubject는 게시한 마지막 값만 저장했다는 점을 제외하고 ReplaySubject와 유사합니다. 또한 BehaviourSubject 에는 초기화 시 T 형식의 기본값이 필요합니다. 이 값은 주체가 아직 다른 값을 받지 못한 경우 관찰자에게 전송됩니다. 즉, 제목이 이미 완료되지 않은 한 모든 구독자는 구독에서 즉시 값을 받게 됩니다. AsyncSubject는 재생 및 동작 주체와 유사하지만 마지막 값만 저장하고 시퀀스가 완료된 경우에만 게시합니다. 관찰 가능한 원본이 핫이고 관찰자가 구독하기 전에 완료될 수 있는 상황에 AsyncSubject 형식을 사용할 수 있습니다. 이 경우 AsyncSubject 는 여전히 마지막 값을 제공하고 향후 구독자에게 게시할 수 있습니다.