我有要做的事件列表。所以我将订阅者添加到订阅列表中。订户完成工作后,必须取消订阅。用户完成时尚不清楚。只有用户自己知道。
最佳设计模式或解决方案是什么。
我使用了观察者模式。
这是我的Observable:
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);
}
}
//...
}
这是观察者:(可以有0到多个观察者)
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();
}
//...
}
这是像往常一样实施的Unsubscirber。
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);
}
}
当我尝试在OnNext
事件中部署观察者时出现问题。因为我在foreach循环中而修改了集合,我处理了,即从列表中删除了元素。
您如何处理自己想要取消订阅订阅者的情况?有没有更好的设计模式?
我很欣赏看到不同的方法,而不是使用可观察和观察者。
假设你有这个事件。
public event EventHandler<double> TimeDiff;
您有许多订阅者附加到TimerDiff
并且能够取消订阅。
public class Reciever
{
Jobs listOfJobsToDo;
public void TimeDiffRecieved(double diff)
{
listOfJobsToDo.DoJob(diff);
if(somecondition)
Unsubscribe();
}
}
答案 0 :(得分:0)
由于foreach无法处理我用于循环的集合更改。
在这种情况下,我们知道当观察者工作时,它可以自行处理。和其他人不受影响。
以下是对提供者的更正。
public void OnTimingsRecieved(double timing)
{
for (int i = 0; i < _observers.Count; i++)
{
var count = _observers.Count; // save count in case it may change.
var observer = _observers[i];
observer.OnNext(timing); // it may only dispose it self.
i -= count - _observers.Count; // decrement if observer unsubscribed.
}
}