私は行う予定のリストがあります。だから、サブスクリプションのリストにサブスクライバを追加します。加入者が仕事を終えた後、加入者は自身を退会しなければならない。加入者が終了した時点は不明である。加入者自身がそれを知っているだけです。その中の加入者をどのように退会させるのですか
最適なデザインパターンまたは解決策は何でしょうか。
私はオブサーバパターンを使用しました。
これは私の観察可能である:
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です。私は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 –