2012-03-19 57 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)。