سؤال

I have this:

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.

Which is a nice little bit of code from this post that got me started down this road. The goal is to ping a web service (via the CheckFolder() method) every time the Timers publish, based on a given start time and interval.

The trouble is, every time I run the program it outputs a single message for the first Watcher, and then the program exits without error. It gets the first answer, and it's finished.

How do get it to wait for the other publications from all the timers?

I'm almost positive I'm not asking this question the right way, but hopefully a little feedback will help me refine my question.

Thanks.

هل كانت مفيدة؟

المحلول

This is likely because Subscribe is a non-blocking call. I.e. if you have;

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

You'll probably find it prints nothing (or maybe "Got 0", depending on how your PC is feeling)

If you stop Main from exiting, by waiting for a key to be pressed, like this:

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

Then it should keep printing out values until you press a key.

The thing to remember is that having an activating subscription, isn't enough to keep your programming running. If you're writing an application with some UI, then you'll usually have a message loop - which will your program alive until you close the window. But that isn't the case for console apps, once you get to the end of main, that's the end of your program.

So you need to find a way to avoid your app exiting before you're reading. Waiting for a specific key to be pressed is a common way to do it, so that may work for you. 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)
    {
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top