随笔 - 355  文章 - 8 评论 - 512 trackbacks - 19

IObservable的两个扩展,主要用来和C# 5.0中的异步操作配合使用的。

 1     static class ObservableExtend
 2     {
 3         public static IDisposable Subscribe<T>(this IObservable<T> stream, Action<T, CancellationToken> onNext)
 4         {
 5             CancellationTokenSource cts = new CancellationTokenSource();
 6             return stream.Subscribe(i =>
 7             {
 8                 cts.Cancel() ;
 9                 cts = new CancellationTokenSource();
10 
11                 try { onNext(i, cts.Token); }
12                 catch { }
13             });
14         }
15 
16         #region IAsyncEnumerator
17         public interface IAsyncEnumerator<T>
18         {
19             Task<bool> MoveNext();
20             T Current { get; }
21         }
22 
23         class AsyncEnumerator<T> : IAsyncEnumerator<T>
24         {
25 
26             TaskCompletionSource<bool> tcs;
27             IObservable<T> stream;
28 
29             public AsyncEnumerator(IObservable<T> stream)
30             {
31                 this.stream = stream;
32                 this.tcs = new TaskCompletionSource<bool>();
33 
34                 stream.Subscribe(
35                     item =>
36                     {
37                         var tcs = this.tcs;
38                         this.tcs = new TaskCompletionSource<bool>();
39                         this.Current = item;
40                         tcs.SetResult(true);
41                     },
42                     err => tcs.SetException(err),
43                     () => tcs.SetResult(false));
44             }
45 
46             public Task<bool> MoveNext()
47             {
48                 return tcs.Task;
49             }
50 
51             public T Current { getprivate set; }
52         } 
53         #endregion
54 
55         //该方法不适用于类似Observable.Range()那样在Subscribe()函数中同步主动推送数据的IObservable。
56         public static IAsyncEnumerator<T> ToAsyncEnumerable<T>(this IObservable<T> stream)
57         {
58             return new AsyncEnumerator<T>(stream);
59         }
60     }

 

为了简单,下面举的例子不是很典型,将就看了。

 1     var stream = Observable.Interval(TimeSpan.FromSeconds(1)).Take(10);
 2 
 3     stream.Subscribe((item, cancel) =>
 4     {
 5         if (cancel.IsCancellationRequested)
 6             return;
 7         Console.WriteLine("### " + item);
 8     });
 9 
10     stream.Subscribe(Console.WriteLine);
11 
12     TaskEx.Run(async () =>
13     {
14         var enumerator = stream.ToAsyncEnumerable();
15         while (await enumerator.MoveNext())
16         {
17             Console.WriteLine(">>> " + enumerator.Current);
18         }
19         Console.WriteLine("finished");
20     });

 

posted on 2012-02-23 22:18 天方 阅读(82) 评论(0) 编辑 收藏