3

EventLogC#と.Netのクラスを使用してWindowsイベントログに書き込むコードで断続的な問題が発生します。

基本的に、このコードは日常的に完全に機能しますが、ごくまれに、次のようなエラーが発生し始めます。

"System.ArgumentException:カスタムログ名の最初の8文字のみが重要であり、指定された名前の最初の8文字を使用する別のログがシステムにすでに存在します。指定された名前:'アプリケーション'、既存のログの名前:'応用'。"

ログの他の情報から、影響を受けるコールスタックは次のようになっていることがわかります-実際に既存のLB_Emailログに書き込もうとしていることがはっきりとわかります(LogEmail最初に呼び出されます)。

public static void LogEmail(string to, string type)
{
    string message = String.Format("{0}\t{1}\t{2}", DateTime.Now, to, type);
    Log(message, "LB_Email", EventLogEntryType.Information);
}

private static void Log(string message, string logName, EventLogEntryType type)
{
    using (EventLog aLog = new EventLog())
    {
        aLog.Source = logName;
        aLog.WriteEntry(message, type);
    }
}

エラーが発生し始めると、イベントログへのアクセスがLB_Email何らかの理由でロックされているように見えます。特定のイベントログのプロパティを表示すると、ほとんどの情報がグレー表示されて変更できないことが示され、他のプロセスもそのログにログを記録できないように見えます。ただし、「LB_Error」ログにログを記録し、期待どおりに機能し続けるtry-catchを介して、エラー(上記と同じLogメソッドを使用)が表示されます。

このコードをマルチスレッドアプリケーションから呼び出していますが、上記のコードがスレッドセーフであるかどうかを識別できませんでした。

また、プロセスを強制終了して再起動した後、問題のログが正常に機能していることも確認できます...また、エントリがいっぱいになったときにエントリを再利用するための適切な設定がありました...それは問題ではないと思います。

私はあなたの考えや提案を聞いてみたいです。

4

2 に答える 2

4

ドキュメントには次のように記載されています。

Source を使用して一度に書き込むことができるログは 1 つだけです

したがって、この問題は、マルチスレッドアプリLogが同じソースに対して、特定の時間に複数回メソッドを呼び出すことが原因であると思われます。

これらのイベントをログに記録するには、静的クラス (またはメソッド) の代わりに、スレッドセーフなシングルトン クラスを使用することをお勧めします。

編集:

Jon Skeet のシングルトンに関する優れた記事があります。

シングルトン クラスを実装したくない場合は、次のようにすることができます。

    static readonly object lockObj = new object();

    public static void LogEmail(string to, string type)
    {
        string message = String.Format("{0}\t{1}\t{2}", DateTime.Now, to, type);
        Log(message, "LB_Email", EventLogEntryType.Information);
    }

    private static void Log(string message, string logName, EventLogEntryType type)
    {
        lock (lockObj)
        {
            using (EventLog aLog = new EventLog())
            {
                aLog.Source = logName;
                aLog.WriteEntry(message, type);
            }
        }
    }

これで問題が解決することを願っています。

于 2008-11-28T09:45:42.053 に答える
0

ありがとうブルーノ、

では、Log メソッドの EventLog インスタンスが、別のスレッドでの同じメソッド呼び出しの EventLog インスタンスと異なると考えるのは間違っていますか? それとも、静的メソッド内のオブジェクト インスタンスについて混乱しているだけですか?

OK、Log(...) メソッドへのいくつかのラッパー メソッドがあります。Log メソッドをシングルトン クラスに移動し、ラッパー (LogEmail、LogXxxx、LogYyy など) を変更すると、Log.Zzzz インターフェイスを同じままにできますが、シングルトン LogSingleton.Instance.Log(...) のセキュリティを活用できます。または、異なるログに書き込みたいので、それぞれに独自の LogSingletonXxx が必要ですか?

あなたは私が混乱していることを知ることができます:)はい-同期コードを本当に感謝します:)

ニジ

于 2008-11-28T10:43:51.453 に答える