8

.NET 4.5 に含まれていたEventSourceクラスを介して、.NET アプリケーションでEvent Tracing for Windows (ETW)を使用しようとしています。私は次のようにサブクラス化し、 (モック目的で)インターフェイスを実装しようとしています:EventSourceMyEventSourceIMyEventSource

public interface IMyEventSource
{
  void Test();
}

public class MyEventSource : EventSource, IMyEventSource
{
  public static MyEventSource Log = new MyEventSource();

  [Event(1)]
  public void Test()
  {
    this.WriteEvent(1);
  }
}

PerfViewを実行してこのコードを実行すると、IndexOutOfRangeExceptionへの呼び出しで が発生しWriteEventます。コードを変更してインターフェイスを削除すると...

public class MyEventSource : EventSource
{
  public static MyEventSource Log = new MyEventSource();

  [Event(1)]
  public void Test()
  {
    this.WriteEvent(1);
  }
}

...その後、すべてが正常に機能します。

両方のケースでテストに使用したコードは次のとおりです。

static void Main(string[] args)
{
  MyEventSource.Log.Test();
}

EventSource単純にインターフェイスを実装しているのに、サブクラスが壊れるのはなぜですか?

関連記事はこちら。

4

5 に答える 5

12

質問をした時点で、@LarsSkovslund からの回答は正しかったです。ただし、 Microsoft .Diagnostics.Tracing.EventSourceの安定版では、Microsoftはブログ投稿に従ってこれを変更しました

RTM リリースでは、特定の高度な使用シナリオを有効にするために、イベント ソースの検証規則の一部を緩和しました。

この領域の 2 つの変更点:

  • EventSource タイプは、インターフェースを使用して共通のロギング ターゲットを定義する高度なロギング システムでイベント ソース タイプを使用できるようにするインターフェースを実装できるようになりました。

  • ユーティリティ イベント ソース タイプ (EventSource から派生する抽象クラスとして定義) の概念が導入され、プロジェクト内の複数のイベント ソース タイプ間でコードを共有できるようになりました (最適化された WriteEvent() オーバーロードなど)。

.NET Framework で提供されるSystem .Diagnostics.Tracing.EventSource は、.NET 4.6以降でこれらのシナリオをサポートします。

于 2014-04-19T09:03:19.263 に答える
5

イベント ソースにインターフェイスを実装させることはできませんが、インターフェイスを実装する別のクラスでラップすることは可能です。(これはアダプター設計パターンのインスタンスです)

public class EventSourceAdapter : IEventSource
{
    private MyEventSource log;

    public EventSourceAdapter(MyEventSource log)
    {
        this.log = log;
    }

    public void Test()
    { 
        log.Test()
    }
}
} 
于 2013-05-16T07:18:32.587 に答える
1

本日 (2014 年 9 月 29 日) の時点で、元の投稿者が提供したコードは、.NET 4.5 に同梱されているネイティブ コードでは機能しません。それでも「IndexOutOfRange」例外が生成され、彼が言うように、これは ETW イベントが監視されている場合にのみ行われます (私は PerfView を使用しています)。

そうは言っても、nuget.org の Microsoft EventSource ライブラリを使用して .NET バージョン 4.0 を確認したところ、彼のコードはそれで動作します。

次に、.NET バージョン 4.5 プロジェクトの nuget から Microsoft EventSource ライブラリをインストールしました。ネイティブ .NET 4.5 ライブラリの System.Diagnostics.Tracing.EventSource からではなく、Microsoft.Diagnostics.Tracing.EventSource から継承するようにしました。これは機能しましたが、[Microsoft.Diagnostics.Tracing.Event(int)] 属性を使用して、インターフェイスから継承したメソッドをマークする必要があることもわかりました。

また、説明できない奇妙な動作も観察しました。一部のイベントが、メソッド名ではなく「EventID(0)」という名前で PerfView に表示されることがあります。時々、予期しない IndexOutOfRange 例外が発生しました。前回の試行からの登録がメモリに残っていると推測できます。試行の間に EventSource クラスの名前を変更し始めましたが、これらの問題は発生しなくなりました。

JR

于 2014-09-29T19:25:50.770 に答える