【问题标题】:EventLog Intermittent ExceptionEventLog 间歇性异常
【发布时间】:2008-11-28 09:03:55
【问题描述】:

我在使用 C# 和 .Net 的 EventLog 类写入 Windows 事件日志的一些代码时遇到了间歇性问题。

基本上,这段代码每天都能完美运行,但我们偶尔会开始遇到如下错误:

"System.ArgumentException: 只有 自定义日志的前八个字符 名称很重要,并且有 系统上已经有另一个日志 使用前八个字符 给出的名称。给定的名称: '应用程序',现有日志的名称: '应用'。”

我可以从我们日志中的其他信息中确定受影响的调用堆栈是这样的 - 您可以清楚地看到我实际上正在尝试写入现有的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 方法),并且继续按预期运行。

我从一个多线程应用程序中调用此代码,但我无法确定上面的代码是否是线程安全的。

我还可以确认有问题的日志在终止并重新启动进程后再次正常工作......并且它具有适当的设置以在条目满时重用......虽然我不认为这是问题.

我很想听听您的想法和建议。

【问题讨论】:

    标签: multithreading event-log


    【解决方案1】:

    documentation 声明:

    你只能使用Source来写 一次记录一个日志

    所以我怀疑这个问题是由您的多线程应用程序在给定时间多次调用Log 方法引起的,并且针对同一个源。

    我建议您使用线程安全的单例类代替静态类(或方法)来记录这些事件。

    编辑:

    Jon Skeet 在单身人士身上有一个 excellent article

    如果你不想实现一个单例类,你可以这样做:

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

    希望这能解决您的问题。

    【讨论】:

    • 感谢布鲁诺的链接和最近的编辑......具有讽刺意味的是,我今天在寻找其他信息来源时发现了那篇文章!尼日
    【解决方案2】:

    谢谢布鲁诺,

    那么,我是不是误以为 Log 方法中的 EventLog 实例与不同线程中同一方法调用中的 EventLog 实例不同?还是我只是对静态方法中的对象实例感到困惑?

    好的,所以我对 Log(...) 方法有几个包装器方法。如果我将 Log 方法移动到单例类中,更改了包装器(LogEmail、LogXxxx、LogYyy 等),那么我可以保持我的 Log.Zzzz 接口相同,但利用单例 LogSingleton.Instance.Log(...) 的安全性从当前日志。或者因为我想写入不同的日志,每个日志都需要自己的 LogSingletonXxx 吗?

    你可以看出我很困惑 :) 是的 - 我非常感谢一些同步代码 :)

    尼日

    【讨论】:

    • Nij,EventLog 类下面的代码不知道如何处理同一个 Source 每次多个请求。即使您创建不同的 EventLog 实例,它们也必须与 Source 属性表示的相同静态资源竞争。
    猜你喜欢
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    相关资源
    最近更新 更多