举个简单例子:
using System.Threading; using System.Reactive.Linq; static Action action = () => { Console.WriteLine("Start reading From DB"); for (int i = 0; i < 5; i++) { Console.Write("."); Thread.Sleep(1000); } Console.WriteLine("\nReading From DB Finished"); }; static void Main(string[] args) { Console.WriteLine("main thread started"); lab0(); Console.WriteLine("Waiting for enter to finish the main thread"); Console.ReadLine(); } static void lab0() { action(); // main thread will be stopped here for 5 sec. }运行的话主thread会被block 5秒钟,如果是图形界面,UI会死掉5秒钟。不好,换多线程
static void lab0() { ThreadStart ts = new ThreadStart(action); Thread t = new Thread(ts); t.Start(); }这样就和谐了,不过这样写起来太麻烦了,而且ThreadStart(action) 的参数必须是一个void() target,如果我想返回一些值该怎么办?一旦返回了值我还想利用这些返回值做些事情该怎么办?我相信肯定有别的繁琐的办法,但使用Rx会更美观大方一些,现在用Rx重写lab0()
static void lab0() { Observable.Start(action); }执行效果和多线程的版本一样,没有任何区别,但是就一行话,Observable.Start()会把一个同步的线程变成异步来执行,那么如果我有返回值该怎么办?把action改写一下:
static Func<string> action = () => { Console.WriteLine("Start reading From DB"); for (int i = 0; i < 5; i++) { Console.Write("."); Thread.Sleep(1000); } Console.WriteLine("\nReading From DB Finished"); return "NASA"; };现在action会在5秒钟后返回一个“NASA”的字符串,我想要打印这个字符串,把lab0()变一下:
static void lab0() { Observable.Start(action).Subscribe(s => Console.WriteLine(s)); }这样,Rx会异步的执行action,当action结束返回一个string的时候,Rx会把这个string当作输入参数传递给Subscribe(s => Console.WriteLine(s)); Subscribe()是一个IObservable的扩展函数(Extension Method), Observable.Start()会返回一个IObservable的对象