Reactive Extensions:为什么会立即退出?

时间:2013-08-24 06:10:52

标签: system.reactive reactive-programming

我正在阅读IntroToRx,我在使用示例代码方面遇到了一些麻烦。这是我的代码的总和:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LearningReactiveExtensions
{
  public class Program
  {
    static void Main(string[] args)
    {
        var observable = Observable.Interval(TimeSpan.FromSeconds(5));
        observable.Subscribe(
          Console.WriteLine, 
          () => Console.WriteLine("Completed")
        );
        Console.WriteLine("Done");
        Console.ReadKey();
    }

  }
}

如果我正确地理解了这本书,那么应该在控制台上写一个数字序列,每隔五秒永远,因为我从不Dispose()序列。

然而,当我运行代码时,我得到的只是最后的“完成”。没有数字,没有“完成”,只有“完成”。

我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

我假设您没有耐心等待5秒钟,否则您会看到代码正常工作。

谨记Rx的主要想法是 Observable.Subscribe几乎会立即将控制权交还给调用方法。换句话说, Observable.Subscribe在生成结果之前不会阻止。因此,仅在五秒钟后才会调用对Console.WriteLine的调用。

答案 1 :(得分:0)

你需要一些方法让主线程等待你正在做的事情。如果您愿意,可以使用信号量

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LearningReactiveExtensions
{
  public class Program
  {
    static void Main(string[] args)
    {
         SemaphoreSlim ss = new SemaphoreSlim(1);
        var observable = Observable.Interval(TimeSpan.FromSeconds(5));
        observable.Subscribe(
          Console.WriteLine, 
          () => {
               Console.WriteLine("Completed");
               ss.Release();
          }
        );
        ss.Wait();
        Console.WriteLine("Done");
        Console.ReadKey();
    }

  }
}

虽然在这种情况下可能更好只是写

  static void Main(string[] args)
   {
        SemaphoreSlim ss = new SemaphoreSlim(1);
        Observable.Interval(TimeSpan.FromSeconds(5)).Wait();
        Console.WriteLine("Completed");
        Console.WriteLine("Done");
        Console.ReadKey();
   }