2013-08-24 22 views
0

我在阅读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

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

Rx一起记住的主要想法是,Observable.Subscribe将几乎立即返回控制到调用方法。换句话说,Observable.Subscribe不会阻止,直到结果产生。因此对Console.WriteLine的呼叫只会在五秒后被调用。

+0

这并不是说我缺乏耐心;相反,我认为除非顺序已经完成,否则“完成”将不会显示,例如,从来没有在这个例子。我理解的根本缺陷。 –

+0

我很担心我已经为Done条款和Completed做了一个例子。如果您将“已完成”这个单词换成“已完成”,那么您的程序会更准确。理想情况下也捕获订阅,然后将其置于'ReadKey()'之后。 –

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(); 
    } 
+0

我认为你不应该在这样一个简单的例子中使用原始的等待句柄和Rx。海事组织,这样做会破坏学习Rx的观点。 –

+0

你必须在main中使用wait。您不能将其标记为异步并使用等待。 – bradgonesurfing