C# 从事件中可观察到
我是Rx的新手,在查看一些样本时,遇到了以下问题:C# 从事件中可观察到,c#,system.reactive,C#,System.reactive,我是Rx的新手,在查看一些样本时,遇到了以下问题: Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>( h => new RoutedEventHandler(h), h => Loaded += h, h => Loaded -= h) .Select(_ => true)
Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
h => new RoutedEventHandler(h),
h => Loaded += h,
h => Loaded -= h)
.Select(_ => true)
.StartWith(IsLoaded)
.Where(l => l)
.Take(1)
.Subscribe(_ => Console.WriteLine("loaded");
Observable.FromEventPattern(
h=>新的路由EventHandler(h),
h=>Loaded+=h,
h=>Loaded-=h)
.选择(=>true)
.StartWith(已加载)
.其中(l=>l)
.采取(1)
.Subscribe(=>Console.WriteLine(“已加载”);
我试图解构这句话,找出它在做什么,但我并不是100%清楚
我理解FromEventPattern是如何将加载的事件转化为一个可观察的序列的。现在,当IsLoaded为真时(IsLoaded)将触发选择是否只是从RoutedEventTargets获取其信息
现在,我不知道为什么会有StartsWith。StartsWith会将一个值序列预先添加到一个可观察序列中。那么它只是将IsLoaded的值添加到列表的开头吗?在Select发生后,它不会已经存在了吗
.Where未应用任何类型的过滤器,因此.Take将只获取序列的第一个值(在本例中不再使用该值)。然后它订阅,并且仅在加载控件时写入控制台
这一分析基本正确吗
还有,关于调试这些东西的任何提示(意思是,在链的不同阶段序列是什么样子的)?我只需附加调试器就可以获得信息,但我想知道是否还有其他常用的技巧/提示。大多数可观察运算符的工作方式与同名可枚举运算符的工作方式相同。如果您有使用这些运算符的经验,这里将非常有用 为了解决这个问题,让我们先用一个整数数组,而不是可观察的数组
int[] data = {1, 2, 3, 4};
这会将表达式更改为
var results = data.Select(_ => true)
.StartWith(IsLoaded)
.Where(l => l)
.Take(1);
foreach (var r in results)
{
Console.WriteLine("loaded");
}
如果在表达式的每个阶段创建一个数组,则会得到:
Select - {true, true, true, true}
StartWith - {value of IsLoaded, true, true, true, true}
Where - (if IsLoaded is true) {true, true, true, true, true}
(if IsLoaded is false) {true, true, true, true}
Take - {true}
对于IEnumerables,这样做没有多大意义,因为您总是会得到一个为真的值(除非源数组为空且IsLoaded为假)
将其与IObservable一起使用是为了在加载对象时生成一个信号
- 如果订阅时已加载对象,则
is将提供信号StartWith
- 但是,如果对象未加载,
将为false,IsLoaded
将过滤掉它,当事件触发时,它将触发通知。Where
将忽略事件产生的实际数据,只传递一个true,该true将通过Select
过滤器继续执行Where
仅用于触发通知一次,无论它来自Take
,因为加载完成时对象已加载,或事件(通过StartWith
)已加载Select
Zip
操作符的表示
很容易看出,它将来自任一流的两个值配对
调试序列的一种简单方法是在两者之间使用Do
操作符,如下所示:
static IObservable<T> Log<T>(this IObservable<T> stream, string name)
{
return stream.Materialize()
.Do(n => Console.WriteLine("{0} - {1}",name, n))
.Dematerialize();
}
您可以看到每个值沿管道向下传播:
Timer - OnNext(0)
Where - OnNext(0)
Timer - OnNext(1)
Timer - OnNext(2)
Where - OnNext(2)
Timer - OnNext(3)
Sample - OnNext(2)
Take - OnNext(2)
Take - OnCompleted()
我对RX也是新手。根据使用情况,我怀疑<>代码> 不是必需的。对于进程中的任何步骤,您可以手动注入DO方法并将结果输出到控制台(C++中,这是已知的PrtTf调试)。。您可能还想试用该工具,以直观地查看运行时的情况。@neontapri,如果订阅时IsLoaded属性的值为false,则where将删除false值,就像在StartWith操作符中一样。请注意。所讨论的代码只是在对象(控件?)运行时生成一个单值序列若在订阅时已加载,则立即推送一个值,否则在加载时将推送该值。
Timer - OnNext(0)
Where - OnNext(0)
Timer - OnNext(1)
Timer - OnNext(2)
Where - OnNext(2)
Timer - OnNext(3)
Sample - OnNext(2)
Take - OnNext(2)
Take - OnCompleted()