计算主题的所有订阅

时间:2016-05-26 10:59:46

标签: c# unity3d system.reactive reactive-programming observer-pattern

我有一个主题,我订阅了当游戏中确定的事件发生时应该调用的方法。

select count(*), expert_id from wp_lead_action_records_date_status 
where last_updated_date >= curdate() - INTERVAL DAYOFWEEK(curdate())+6 DAY
   AND last_updated_date < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY 
   AND entry_status ='Completed' 
   AND entry_status ='Completed'
group by expert_id
order by count(*) desc
limit 3

有些实例订阅了该主题。

public Subject<SomeEvent> TestSubject = new Subject<SomeEvent>();

我的目标是计算已订阅该主题的方法数量。我已经看过一些使用Count()扩展的例子但是我需要一个int作为返回值,所以我可以在其他地方使用它,而Count()返回一个IObservable。

TestSubject.Subscribe(MyMethod);

有没有办法获得某个主题的订阅数量,或者我是否需要手动跟踪它们(拥有一个public int SubjectSubcriptions并在每次订阅方法时添加1)?

2 个答案:

答案 0 :(得分:4)

最简单的方法是使用主题包装器创建自己的ISubject实现。

public class CountSubject<T> : ISubject<T>, IDisposable
{
    private readonly ISubject<T> _baseSubject;
    private int _counter;
    private IDisposable _disposer = Disposable.Empty;
    private bool _disposed;

    public int Count
    {
        get { return _counter; }
    }

    public CountSubject()
        : this(new Subject<T>())
    {
        // Need to clear up Subject we created
        _disposer = (IDisposable) _baseSubject;
    }

    public CountSubject(ISubject<T> baseSubject)
    {
        _baseSubject = baseSubject;
    }

    public void OnCompleted()
    {
        _baseSubject.OnCompleted();
    }

    public void OnError(Exception error)
    {
        _baseSubject.OnError(error);
    }

    public void OnNext(T value)
    {
        _baseSubject.OnNext(value);
    }

    public IDisposable Subscribe(IObserver<T> observer)
    {
        Interlocked.Increment(ref _counter);
        return new CompositeDisposable(Disposable.Create(() => Interlocked.Decrement(ref _counter)),
                                       _baseSubject.Subscribe(observer));
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                _disposer.Dispose();
            }
            _disposed = true;
        }
    }
}

答案 1 :(得分:1)

我很好奇这是否仅用于测试目的。如果是这样,那么Rx-Testing nuget包就会提供工具来为您提供这些信息。

e.g。你可以验证像这样的单元测试中的订阅数量

TestScheduler scheduler = new TestScheduler();
var obs = scheduler.CreateColdObservable(
      ReactiveTest.OnNext(1, "foo"),
      ReactiveTest.OnNext(1000, "bar"),
    );

//Do some work that should add subscriptions.
Assert.AreEqual(expectedSubriptionCount, obs.Subscriptions);