2012-03-19 58 views
1

执行上下文嵌套活动执行上下文嵌套活动

嗨,我 想知道多一点约而至“嵌套事件”的IObserver<T>的执行上下文相关的。

基本上当我把它比作LINQ到IEnumerable的,我建立一个表达式树,当我打电话像ToList()我被执行...等 例如

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

这只是一种表达这是得到执行(我假设当我执行FirstOrDefault)... 这是如何与IObservable世界工作?我认为它会工作几乎相同...我会很高兴有这个输入...

这涉及到我真正的问题,因为我有一些事件,这是某种事件容器。

event EventHandler<ContainerEventArgs> ContainerReady; 

ContainerEventArgs将包含坐标数组...我必须再做一次手术那里得到了我要寻找的特定坐标(centercoordinate)。 中心坐标是我真正喜欢观察的事情。当这种变化我想获得通知,..

在没有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风格吗?任何改进建议?

回答

1

您的需求是真正适合的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 to SQL)。