質問
C#および.Netの EventLog
クラスを使用して、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メソッドを使用)が表示され、期待どおりに機能し続けます。
このコードをマルチスレッドアプリケーションから呼び出していますが、上記のコードがスレッドセーフかどうかを特定できませんでした。
また、プロセスを強制終了して再起動した後、問題のログが正常に機能していることを確認できます...そして、いっぱいになったときにエントリを再利用するための適切な設定がありました...それは問題ではないと思いますが。
あなたの考えや提案を聞きたいです。
解決
ドキュメントには次のことが記載されています。
ソースのみを使用して書き込むことができます 一度に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);
}
}
}
これで問題が解決することを願っています。
他のヒント
ブルーノに感謝、
では、LogメソッドのEventLogインスタンスは、別のスレッドの同じメソッド呼び出しのEventLogインスタンスとは異なると考えるのは間違っていますか?または、静的メソッド内のオブジェクトインスタンスについて混乱しているだけですか?
OK、それでLog(...)メソッドのラッパーメソッドがいくつかあります。 Logメソッドをシングルトンクラスに移動し、ラッパー(LogEmail、LogXxxx、LogYyyなど)を変更した場合、Log.Zzzzインターフェイスは同じままにできますが、シングルトンLogSingleton.Instance.Log(...)のセキュリティを活用できますまたは、異なるログに書き込みたいので、それぞれが独自のLogSingletonXxxを必要としますか?
混乱していると言うことができます:)はい-同期コードを本当に感謝します:)
Nij