C#事件日志EntryWrittenEventHandler负荷不只是一个事件

问题描述 投票:0回答:2

我创建了一个小程序(服务或控制台,使用相同的测试结果两者)来观看Windows安全事件日志中的特定事件ID唯一,然后在最后一个事件与此ID来通过执行一个动作。

这工作了一段时间确定后,突然,一个一天几次,程序进入,并得到与指定的事件ID的所有事件在整个日志(而不仅仅是最后一个)。

这里是我的代码:

class Program
{   // These are the events I want to listen to
    public static string[] eventsToListen = { "4727", "4730", "5136", "5139" };

    static void Main(string[] args)
    {
        EventLog eventLog = new EventLog("Security", Environment.MachineName);

        eventLog.EntryWritten += new EntryWrittenEventHandler(OnEntryWrittenAsync);
        eventLog.EnableRaisingEvents = true;

        Console.ReadLine();
    }

    private static void OnEntryWrittenAsync(object sender, EntryWrittenEventArgs e)
    {
        if (eventsToListen.Contains(e.Entry.InstanceId.ToString()))
        {
            Task.Factory.StartNew(() => writeToRemoteLog(e.Entry));
        }
    }

    private static void writeToRemoteLog(EventLogEntry entry)
    {
        string logMessage = null;

        if (EventLog.Exists("DCGroupEvents", "targetMachineName"))
        {
            try
            {
                var log = new EventLog("DCGroupEvents", "targetMachineName");
                log.Source = "DCGroupEvents";
                String strMessage = entry.Index.ToString();
                log.WriteEntry(strMessage);
                log.Close();
                logMessage = entry.InstanceId.ToString() + "/" + entry.TimeWritten.ToString() + "/" + entry.Index.ToString() + " written to eventlog";
            }
            catch (Exception e)
            {
                logMessage = e.Message;
            }
        }
        else
        {
            logMessage = "Log does not exist";
        }
        Console.WriteLine(logMessage);
        logMessage = null;

    }
}

我怎样才能避免这种下载所有的事件(符合条件),每日数次的?

很多感谢的人谁知道这一点,我有点停留在那一刻。

c# event-log
2个回答
0
投票

该系统响应WriteEntry只有在发生至少六秒钟,最后写事件之前。这意味着你将只有六秒钟时间间隔内收到一个EntryWritten事件通知,即使出现超过一个事件日志的变化。如果插入调用WriteEntry之间有足够长的休眠时间间隔(10秒左右),你不太可能错过的事件。但是,如果写事件发生比较频繁,你可能不会收到事件通知,直到下一次的时间间隔。通常情况下,错过了事件通知没有丢失,而是推迟。

来源:https://social.msdn.microsoft.com/Forums/vstudio/en-US/b0314be2-3b75-4a21-aabc-4777cd8ba100/eventlogentrywritten-firing-for-events-in-the-past?forum=netfxbcl


0
投票

虽然不是理想的解决方案,你可以尝试使用映射表通过实施存储事件的事件属性和索引ID字典来解决这个问题。创造条件,验证和更新映射表,并返回一个布尔结果的方法。然后,而不是执行时的事件被触发的活性,通过调用ValidatedUpdate(PARAMS)执行验证和基于该结果进行活动。所述ValidatedUpdate(PARAMS)方法检查1;如果事件写在现在的2天;如果索引ID已经存在于映射表3;如果事件ID是一样的,你需要过滤的东西。

当这些条件匹配,那么只有它被确定为一个“新”事件的那一天。然后,将条目添加到字典和一个布尔结果可以为未来的跟踪返回。为了减少臃肿的定时器可以实现通过刷新值,将“干净”的映射表,每天的基础上。喜欢的东西下面

    private ConcurrentDictionary<int, DateTime> mappingTable;

    private bool ValidateAndUpdate(int id, DateTime entry)
    {
        try
        {
            if(!mappingTable.ContainsKey(id) && entry.TimeStamp > DateTime.Today.Date)
            {
                mappingTable.TryAdd(id, entry);

                return true;
            }
            else
            {
                return false;
            }
        }
        catch(Exception exception)
        {
            //handle exception event
        }
    }

    private void OnEntryWritten(object sender, EntryWrittenEventArgs e)
    {
        //preceding code here

        if(ValidateAndUpdate(e.Entry.Index, entry) == true)
        {
            //perform operation
        }
        catch(Exception exception)
        {
            //handle exception event
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.