具有嵌套事件的IOobservable上的执行上下文



执行上下文嵌套事件

嗨,我想了解更多关于IObserver<T>的执行上下文以及与"嵌套事件"相关的信息。

基本上,当我将其与linq和IEnumerable进行比较时,我会建立一个表达式树,当我调用ToList()等时,我就会被执行。例如

Var singleCustomer = from customer in customers
            Where customer.ID == 2
            Select customer.FirstOrDefault();

这只是一个被执行的表达式(我假设当我执行FirstOrDefault时)…这在IObservable世界中是如何工作的?我想它会几乎一样工作…我会很高兴有一些关于这个…的意见

这与我的真实问题有关,因为我有一些Event,它是某种事件容器。

event EventHandler<ContainerEventArgs> ContainerReady;

ContainerEventArgs会包含一个坐标数组……我必须在那里做一个运算,才能得到我要找的特定坐标(中心坐标)。中心坐标是我真正喜欢观察的东西。当这一切发生变化时,我想得到通知,。。

在没有Rx的标准.Net方式中,我会做这样的事情来获取CenterCoordinate的坐标更改事件。

ContainerReady += (s,e) => {
var container = e.GetContainer();
var coordinate = new point[e.CoordinatesArrayLength]();
e.CopyCoordinatesToArray(container);
if(coordinates != null){
  var particularCoordinate = from coordinate in coordinates.where(… center coordinates…).FirstOrDefault();
if(particularCoordinate != null){
  if(CenterCoordinateUpdated != null)
     {
        CenterCoordinateUpdated(this, new CenterCoordinateUpdatedEventArgs(){
           CenterPosition = particularCoordinates;
          }
     }
}
}

假设我有这样的第二个事件:

event EventHandler<CenterCoordinatesUpdatedEventArgs> CenterCoordinateUpdated;

好的,长话短说…现在我该如何处理RX?到目前为止,我所拥有的是:

public IObservable<Container> GetContainers(){
     var containerSource = Observerable.FromeEventPattern< ContainerEventArgs>(this,”ContainerReady”);
var container = from evt in containerSource.Where(x=>x.EventArgs.GetContainer != null)
select evt.GetContainers();
return container;
}

所以这返回了一个IObservable<Container>(),但正如我所说,我对内部值更感兴趣…

我想出了这个…

public IObservable<CenterCoordinates> GetContainers(){
     var containerSource = Observerable.FromeEventPattern< ContainerEventArgs>(this,”ContainerReady”);
var container = from evt in containerSource.Where(x=>x.EventArgs.GetContainer != null)
select evt.GetContainers();
var centerCoordinate = from cc in container
             select GetCenterCoordinates(cc); //Get CenterCoordinates does the Array copy stuff
return centerCoordinate.SkipWhile(x=>x … center condition… );
}

我的SkipWhileGetCenterCoordinates方法有意义吗?还是我订阅了任何事件(与我使用IEnumerable的介绍有关),因为我需要先打开坐标?…什么时候执行Observable表达式树?或者我不需要关注(表演)吗?是否有更好的方法使用主题或发布其他事件来处理此问题?这是RX风格吗?有什么改进建议吗?

您的需求非常适合Rx,您只需要多一点练习:-)

让我试着帮你。我希望我能满足你的要求。

您的查询可以用这种简单的方式编写:

public IObservable<CenterCoordinates> GetContainers()
{
    var containerSource = Observerable.FromeEventPattern<ContainerEventArgs>(this, "ContainerReady");
    var query = containerSource
        .Select(ev => ev.EventArgs.GetContainer) // project event args into containers
        .Where(container => container != null) // filter null containers
        .SelectMany(container => GetCenterCoordinates(container))  // expand the stream of containers into a stream of center coordinates
        .Where(cc => .. center condition ..);  // filter only center that match a certain condition
    return query;
}

如果你喜欢查询语法,你也可以这样写:

public IObservable<CenterCoordinates> GetContainers()
{
    var containerSource = Observerable.FromeEventPattern<ContainerEventArgs>(this, "ContainerReady");
    var query = from ev in containerSource
                let container = ev.EventArgs.GetContainer
                where container != null
                from cc in GetCenterCoordinates(container)
                where cc .. center condition ..
                select cc;
    return query;
}

熟悉SelectMany:它是LINQ中最重要的运算符之一(包括LINQ到对象和Rx)。

还有一个小的更正:我们在这里讨论的LINQ查询没有被编译器翻译成表达式树。它们被翻译成一系列扩展方法,就像我在第一个例子中展示的那样。表达式树用于更复杂的场景(例如LINQ到SQL)。

相关内容

  • 没有找到相关文章

最新更新