나는 할 일 목록이 있습니다. 그래서 구독 목록에 구독자를 추가합니다. 가입자가 일을 마친 후에는 가입자가 스스로 가입을 해지해야합니다. 가입자가 끝나면 알 수 없습니다. 가입자 만이 그것을 알고 있습니다.구독자 내에서 구독을 취소하는 방법
어떤 디자인 패턴이나 솔루션이 가장 좋을까요?
내가 사용 옵저버 패턴.
이
은 내 관찰 가능한 :이는 평소와 같이 구현되는 Unsubscirber입니다internal class EventObserver : IObserver<double>
{
private IDisposable _unsubscriber;
private readonly IReadOnlyList<Event> _events;
public EventObserver(IReadOnlyList<Event> events)
{
_events = events;
}
public void Subscribe(EventProvider provider)
{
_unsubscriber = provider.Subscribe(this);
}
private int _ind;
public void OnNext(double timings)
{
// may move to next event or not. it depends.
// _ind++; may execute or not
if (_ind == _events.Count) OnCompleted(); // time to unsubscribe it self
}
public void OnCompleted()
{
_unsubscriber.Dispose();
}
//...
}
(많은 관찰자에 0이있을 수 있습니다) :
이
internal class EventProvider : IObservable<double>
{
private readonly List<IObserver<double>> _observers = new List<IObserver<double>>();
public IDisposable Subscribe(IObserver<double> observer)
{
// check if observer exist...
_observers.Add(observer);
return new Unsubscriber<double>(_observers, observer);
}
public void OnTimingsRecieved(double timing) // some other event fires this
{
foreach (var observer in _observers)
{
observer.OnNext(timing);
}
}
//...
}
는 관찰자이다 . 내가
OnNext
이벤트 내부 관찰자를 처리 할 때
internal class Unsubscriber<T> : IDisposable
{
private readonly List<IObserver<T>> _observers;
private readonly IObserver<T> _observer;
internal Unsubscriber(List<IObserver<T>> observers, IObserver<T> observer)
{
_observers = observers;
_observer = observer;
}
public void Dispose()
{
if (_observers.Contains(_observer))
_observers.Remove(_observer);
}
}
문제
가 나타납니다. 내가 foreach 루프 내부에 있었기 때문에 컬렉션이 수정되었고 목록에서 삭제 된 요소가 삭제되었습니다.가입자를 구독 취소 할 상황을 어떻게 처리합니까? 더 좋은 디자인 패턴이 있습니까?
나는 관측 가능하고 관찰자를 사용하는 대신 다른 접근법을 보게됩니다.
이 이벤트가 있다고 가정합니다.
public event EventHandler<double> TimeDiff;
는 그리고 당신은 TimerDiff
에 연결된 가입자의 인스턴스가 자신을 취소 할 수 있습니다.
public class Reciever
{
Jobs listOfJobsToDo;
public void TimeDiffRecieved(double diff)
{
listOfJobsToDo.DoJob(diff);
if(somecondition)
Unsubscribe();
}
}
왜 당신은 자신의 관측 대상을 구현하고 있습니까? 그것은 위험으로 가득차 있습니다. 내장 된 Rx 구현을 사용해야합니다. – Enigmativity
알겠습니다. 이 관측기를 제거하고 Rx가 시간을내어 어떻게 작동하는지 확인하려고합니다. @Enigmativity –