【问题标题】:How to unsubscribe a subscriber within it self如何自行取消订阅其中的订阅者
【发布时间】:2017-04-18 06:10:37
【问题描述】:

我有一系列活动要做。所以我将订阅者添加到订阅列表中。订阅者完成其工作后,它必须自行取消订阅。订阅者何时完成是未知的。只有订阅者自己知道。

什么是最好的设计模式或解决方案。

我使用了观察者模式

这是我的 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 循环中并且我已处理,即从列表中删除了元素。

如果您想自行取消订阅订阅者,您将如何处理?有没有更好的设计模式?


我很高兴看到不同的方法,而不是使用 observable 和 observer。

假设你有这个事件。

public event EventHandler<double> TimeDiff;

您有许多订阅者实例附加到TimerDiff,并且可以自行取消订阅。

public class Reciever
{
    Jobs listOfJobsToDo;

    public void TimeDiffRecieved(double diff)
    { 
       listOfJobsToDo.DoJob(diff);
       if(somecondition)
           Unsubscribe();
    }
}

【问题讨论】:

  • 为什么要实现自己的 observables?这充满了危险。您应该使用内置的 Rx 实现。
  • 我明白了。我将删除这些观察者并尝试 Rx 看看它是如何工作的,感谢您的时间。 @Enigmativity

标签: c# events observer-pattern subscribe unsubscribe


【解决方案1】:

由于 foreach 无法处理我使用 for 循环的集合更改。

在这种情况下,我们知道当观察者工作时,它可以自行处置。其他人不受影响。

这是对提供者的更正。

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.
    }
}

【讨论】:

  • 如果你使用这种模式,最好重用现成的解决方案(命名为 Rx (Reactive) 扩展)。
  • 看起来很有趣。这对我来说是全新的事情。生病寻找那个。谢谢顺便说一句。 @Evk
猜你喜欢
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 2012-03-14
  • 2018-08-03
  • 2015-08-24
  • 2018-05-08
相关资源
最近更新 更多