1

実行コンテキストのネストされたイベント

IObserver<T>こんにちは。「ネストされたイベント」の実行コンテキストと関連についてもう少し知りたいと思います。

基本的に、linq-to-IEnumerableと比較すると、式ツリーが作成され、ToList()…などを呼び出すと実行されます。たとえば、

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

これは実行される式にすぎません(実行するときに想定しFirstOrDefaultます)…これは世界でどのように機能しIObservableますか?ほぼ同じように機能すると思います…これについて意見をお聞かせいただければ幸いです…</p>

ある種のイベントコンテナであるイベントがあるので、これは私の本当の質問に関連しています。

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;
          }
     }
}

}

このような2番目のイベントがあると仮定します。

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>()が、私が言ったように、私は内部の値にもっと興味があります…

私はこれを思いついた…</p>

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のイントロに関連する)イベントをサブスクライブしますか?…ObservableExpression-Treeはいつ実行されますか?それとも、その(パフォーマンス)に注意を払う必要はありませんか?サブジェクトを使用してこれを処理したり、他のイベントを公開したりするためのより良い方法はありますか?これはRXスタイルですか?改善の提案はありますか?

4

1 に答える 1

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で最も重要な演算子の1つです(オブジェクトへのLINQとRxの両方)。

そして、ちょっとした修正です。ここで話しているLINQクエリは、コンパイラによって式ツリーに変換されません。これらは、最初の例で示したように、一連の拡張メソッドに変換されます。式ツリーは、より複雑なシナリオ(LINQ to SQLなど)で使用されます。

于 2012-03-23T09:02:04.690 に答える