6

EventLog からのイベントを処理する必要があります。これは、EventRecordWritten イベントにアタッチするEventLogWatcherを使用すると簡単です。ただし、関心のあるクエリ (eventid == 299 || eventid == 500) は、必要以上のイベントを提供します。これがストリームの例です

Event ID   Correlation ID
299        1AD...  (this is actually a guid)  X1
500        1AD...                             X2
500        1AD...
500        1AD...
299        43B...                             Y1
299        EDB...                             Z1
500        43B...                             Y2
500        EDB...                             Z2
500        43B...
500        43B...

イベント 299 と、299 イベントの相関 ID に一致する最初のイベント 500 に関心があります。上記のストリームでそれらをマークしました。これは、私が興味を持っている出力コレクションです。[X1, X2, Y1, Y2, Z1, Z2]これはおそらく、相関 ID をキーとして、のタプルをEventRecord値として使用する辞書です。

{ 1AD.., <X1, X2> }
{ 43B.., <Y1, Y2> }
{ EDB.., <Z1, Z2> }

通常、イベントは順番に (299 の次に 500 のように) 発生しますが、同時実行性の高い状況では、2 つの 299 のイベントが一緒になってから 500 のイベントが発生することが予想されるため、イベントの発生順序に依存したくありません。相関 ID は、それらを相関させるためのキーです (イベントの最初のプロパティですeventRecord.Properties[0]) 。

これはステート マシンで解決できると思いますが、Observable へのクエリによって表される Rx を使用した解決策を誰かが思いついたら興味深いでしょう。これにより、パターン マッチング ロジックが 1 か所に保持されます。

更新:これが解決策への答えです。ギデオンに感謝します。まさに私が必要としていた出発点でした!

var pairs = events
            .Where(e299 => e299.EventArgs.EventRecord.Id == 299)
            .SelectMany(e299 => events.Where(e500 => e500.EventArgs.EventRecord.Id == 500 &&
                                                    e299.EventArgs.EventRecord.Properties[0].Value.ToString() ==
                                                    e500.EventArgs.EventRecord.Properties[0].Value.ToString())
                                    .Take(1), 
                        (e299, e500) => new { First = e299, Second = e500 });

前もってありがとう、マティアス

4

3 に答える 3

5

299 のイベントが常に 500 のイベントの前に来る場合、それでSelectMany十分Whereなはずです。

var events; //declared somewhere

var pairs = from e299 in events
            where e299.eventid == 299
            from e500 in events
            where e500.eventid == 500 &&
                  e299.Correlation == e500.Correlation
            select new with {Correlation = e299.Correlation,
                             First = e299,
                             Second = e500}

ソースに、相関する 299 イベントごとに複数の 500 イベントがある場合は、ラムダ構文に切り替えてTake(1)、2 番目のサブスクリプションに a を追加する必要がある場合があります。

于 2012-04-11T17:42:46.997 に答える
2

JoinsでObservable.Whenを使用することを検討する必要があります。これにより、必要に応じて複雑な結合パターンを作成できます。

たとえば、https://stackoverflow.com/a/3868608/13131およびGuide to System.Reactive.Joinsを参照してください。

于 2012-04-11T20:16:16.063 に答える
0

「ステートマシン」の意味がわかりません。

ただし、(eventid == 299 || eventid == 500) を収集するオブザーバーを作成することもできます。スロットル戦略 (最新の 1000 イベントを収集するか、最新の 1 分かはわかりません) を使用して、299、500 のイベントのペアが同じ GUID を持っていることを検出すると、イベントを発生させ、内部辞書/リストから削除します。イベント。

次に、その親切なオブザーバーは、システムの残りの部分を監視できます。

おそらく、リストはイベントを収集することができ、新しいイベントが検出されると、次のようになります

events.Where(e => e.eventid == newevent.eventid && ((e.id == 299 && newev.id == 500) || (e.id == 500 && newev.id == 299))

GUIDによる辞書を持つ代わりに、パフォーマンスが十分になる可能性があります。

またね、マシュー!

于 2012-04-11T17:14:51.777 に答える