C# 关于反应式延长计时器,我遗漏了什么?

C# 关于反应式延长计时器,我遗漏了什么?,c#,system.reactive,reactive-programming,reactiveui,C#,System.reactive,Reactive Programming,Reactiveui,我有这个: watchers .ToObservable() // needs to be observable .SelectMany(watcher => // working on each watcher Observable // create a timer for the watcher .Timer(watcher.StartTime, TimeSpan.FromHours(watcher.Interval))

我有这个:

watchers
  .ToObservable() // needs to be observable
  .SelectMany(watcher =>         // working on each watcher
    Observable
      // create a timer for the watcher
      .Timer(watcher.StartTime, TimeSpan.FromHours(watcher.Interval))  
      .SelectMany(Observable.FromAsync(
        async () => new { watcher, result = await CheckFolder(watcher.Path) }))) 
  .Subscribe(x => Console.WriteLine(string.Format("Watcher: {0}\tResult: {1}\tTime: {2}", x.watcher.Name, x.result, DateTimeOffset.Now))); // tell everyone what happened.
这是一段很好的代码,让我开始走这条路。目标是在
计时器每次发布时基于给定的开始时间和间隔ping web服务(通过
CheckFolder()
方法)

问题是,每次我运行程序时,它都会为第一个观察者输出一条消息,然后程序会无误退出。它得到了第一个答案,就完成了

如何让它等待所有时间的其他出版物

我几乎可以肯定我问这个问题的方式不对,但希望一些反馈能帮助我完善我的问题


谢谢。

这可能是因为
Subscribe
是一个非阻塞呼叫。如有,

static void Main(string[] args)
{
  Observable.Timer(DateTimeOffset.Now, TimeSpan.FromSeconds(0.5))
            .Subscribe(x => Console.WriteLine("Got " + x));
}
你可能会发现它什么也不打印(或者可能“得到0”,这取决于你的电脑的感觉)

如果您通过等待按键停止Main退出,如下所示:

static void Main(string[] args)
{
    Observable.Timer(DateTimeOffset.Now, TimeSpan.FromSeconds(0.5))
               .Subscribe(x => Console.WriteLine("Got " + x));
    Console.ReadKey();
}
然后它应该一直打印出值,直到你按下一个键

要记住的是,拥有一个激活订阅并不足以让你的程序继续运行。如果您正在编写一个具有某种UI的应用程序,那么通常会有一个消息循环,在关闭窗口之前,该循环将使您的程序处于活动状态。但对于控制台应用程序来说,情况并非如此,一旦你到达main的末尾,你的程序就结束了

因此,在阅读之前,你需要找到一种避免应用程序退出的方法。等待一个特定的键被按下是一种常见的方法,所以这可能对你有用。e、 g

static void Main(string[] args)
{
    Observable.Timer(DateTimeOffset.Now, TimeSpan.FromSeconds(0.5))
              .Subscribe(x => Console.WriteLine("Got " + x));

    while (Console.ReadKey().Key != ConsoleKey.Q)
    {
    }
}

记住这一点的一个简便方法是做正确的事情并捕获订阅,即
var subscription=Observable.Timer(…).subscription(…)现在,您有一个表示订阅的<代码> IDISPOSTABLE ,现在您必须考虑何时清理此资源。这将迫使您思考为什么您的应用程序不会从
static void Main
方法的底部掉出来。