【问题标题】:Reset and Dispose observable subscriber, Reactive Extensions重置和处置 observable 订阅者,反应式扩展
【发布时间】:2017-07-25 15:47:52
【问题描述】:

假设我有这个:

    public class UploadDicomSet 
{ 
    public UploadDicomSet()
    {
        var cachCleanTimer = Observable.Interval(TimeSpan.FromMinutes(2));
        cachCleanTimer.Subscribe(CheckUploadSetList);
        //Start subscriber
    }
    void CheckUploadSetList(long interval)
    {
        //Stop and dispose subscriber
    }
    public void AddDicomFile(SharedLib.DicomFile dicomFile)
    {
        //Renew subscriber, call CheckUploadSetList 2 minutes later
    }
}

1- in CheckUploadSetList 我要处理或完成 observable

2-在AddDicomFile我要重置它

作为方法中的注释。

更新:

我可以通过Timer 来做:

 public class UploadDicomSet : ImportBaseSet
{
    Timer _timer;
    public UploadDicomSet()
    {
        _timer = new Timer(CheckUploadSetList, null, 120000, Timeout.Infinite);
    }

    void CheckUploadSetList(object state)
    {
        Logging logging = new Logging(LogFile);
        try
        {
            _timer.Dispose(); //Stop the subscription
                              //dispose everything
        }
        catch (Exception exp)
        {
            logging.Log(ErrorCode.Error, "CheckUploadSetList() failed..., EXP:{0}", exp.ToString());
        }
    }
    public void AddDicomFile(SharedLib.DicomFile dicomFile)
    {
        _timer.Change(120000, Timeout.Infinite);
    }
}

提前致谢。

【问题讨论】:

  • 谁能告诉我为什么投反对票?
  • 他们几乎从不这样做,可悲的是

标签: c# observable system.reactive


【解决方案1】:

这种事情你应该使用Switch()

类似这样的:

public class UploadDicomSet : ImportBaseSet
{
    IDisposable subscription;
    Subject<IObservable<long>> subject = new Subject<IObservable<long>>();

    public UploadDicomSet()
    {
        subscription = subject.Switch().Subscribe(s => CheckUploadSetList(s));
        subject.OnNext(Observable.Interval(TimeSpan.FromMinutes(2)));
    }

    void CheckUploadSetList(long interval)
    {
        subject.OnNext(Observable.Never<long>());
        // Do other things
    }

    public void AddDicomFile(SharedLib.DicomFile dicomFile)
    {
        subject.OnNext(Observable.Interval(TimeSpan.FromMinutes(2)));
        // Reset the subscription to go off in 2 minutes from now
        // Do other things
    }
}

【讨论】:

  • 感谢您的回答,switch 到底是做什么的?
  • @Aria - .Switch() 切换到最新的内部 observable。因此,它仅通过输出最新的内部可观察对象的值来将IObservable&lt;IObservable&lt;T&gt;&gt; 扁平化为IObservable&lt;T&gt;。这意味着您不必取消订阅并重新订阅即可从可观察对象中获取全新的值。
  • Up+,所以你觉得比老的效率高
  • @Aria - 它更健壮。如果您使用它来将 observable (subject.Switch()) 传递出类,那么您不知道谁订阅了它,但它仍然会产生值。您必须知道谁订阅了其他课程才能重新订阅它们。这有意义吗?
【解决方案2】:

将响应式扩展用于某些计时器功能对我来说似乎有点矫枉过正。为什么不为此使用普通计时器,并在给定时间启动/停止它?

让我给出一个想法。

public class UploadDicomSet : ImportBaseSet
{
    IDisposable subscription;

    public void CreateSubscription()
    {
        var cachCleanTimer = Observable.Interval(TimeSpan.FromMinutes(2));

        if(subscription != null)
            subscription.Dispose();

        subscription = cachCleanTimer.Subscribe(s => CheckUploadSetList(s));
    }

    public UploadDicomSet()
    {
        CreateSubscription();
        // Do other things
    }

    void CheckUploadSetList(long interval)
    {
        subscription.Dispose(); // Stop the subscription
        // Do other things
    }

    public void AddDicomFile(SharedLib.DicomFile dicomFile)
    {
        CreateSubscription(); // Reset the subscription to go off in 2 minutes from now
        // Do other things
    }
}

背景材料

我真的可以推荐这些网站:

http://www.introtorx.com/

http://rxwiki.wikidot.com/101samples

【讨论】:

  • 它不起作用,使用 Option2 时,CheckUploadSetList 每隔 2 分钟调用一次,即使在 subscription.Dispose() 之后也是如此。
  • 感谢您的关注,我没有测试选项 1,我正在调试它并设置断点,它正在调用无穷大,关于选项 1 我将对其进行测试并通知您结果。
  • 让我发布经过测试的代码,如果两分钟内没有更改,我想致电CheckUploadSetList,在AddDicomFile 中出现新的更改,因此订阅者应在两分钟后续订,如果CheckUploadSetList 打了一次电话,我想把所有东西都放在那里,我做了选项 2,它不起作用,我会测试它们并告诉你反馈。
  • 我已经更新了我的答案,它模仿了计时器功能
  • 是的,它与您的新更新一样具有魅力。
猜你喜欢
  • 2013-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多