Получение информации о событии из журнала событий - PullRequest
1 голос
/ 13 июня 2011

Я пытаюсь получить подробности из журнала событий на основе выбора элемента в списке.Я пытался поместить детали в текстовое поле.Мне не удалось найти решение самостоятельно.То, что я сделал, и очень медленно, - это повторение журнала событий и поиск соответствия с индексом журнала, затем отображение сообщения, но это трудоемкая операция.Есть ли гораздо более быстрый способ получить доступ к конкретной записи журнала на основе индекса журнала.Я использую WPF и C #.

private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
    EventLog eventLog1 = new EventLog();
    eventLog1.Log = "System";
    foreach (System.Diagnostics.EventLogEntry entry in eventLog1.Entries)
    {
        var newEntry = entry.Index + "  -  " + entry.EntryType + " -           " + entry.TimeWritten + "     - " + entry.Source;

        backgroundWorker2.ReportProgress(0, newEntry);
    }
}

void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    var newEntry = (string)e.UserState;

   MainWindow.Instance.Dispatcher.BeginInvoke(new Action(delegate() { MainWindow.Instance.listBox1.Items.Add(newEntry); }));
}

И это добавляет каждый элемент в список с индексом элемента, затем я иду и извлекаю индекс:

private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    string p1 = listBox1.SelectedItem.ToString();
    string[] id = Regex.Split(p1, @"([\s])");
    label1.Content = id[0];
    EventLog el = new EventLog();
    el.Log = "System";
    foreach (System.Diagnostics.EventLogEntry entry in el.Entries)
    {
        if (entry.Index.ToString() == id[0])
        {
            label1.Content = entry.Message;
        }

    }
}

ForeachЦикл - это то, что вызывает зависание в пользовательском интерфейсе, но даже если бы я установил его в другом потоке, как я делал при добавлении элементов в список, все равно потребовалось бы некоторое время, чтобы пройти через все это, чтобы получить точный индексЯ ищу.Поэтому я действительно хочу просто перейти к этому индексу и захватить сообщение, а не перебирать весь список в поисках.

1 Ответ

1 голос
/ 14 июня 2011

Посмотрев на ваш код, вот краткая сводка того, что я хотел бы сделать:

Удалить обработчик ProgressChanged. Он предназначен для сообщения о текущем статусе пользователю, который вы надеваетене делайВместо этого вызовите Items.Add в обработчике DoWork.

Создайте EventLog один раз. Это только кажется более приятным и избавляет вас от потенциального создания его в цикле, если вы не будете осторожны.

Вместо анализа текста с помощью регулярных выражений создайте специальный класс. Это действительно важно и избавит вас от боли, когда вам нужно более точное поведение илине хочу отображать индекс вообще.Регулярные выражения являются медленными, и данные, предназначенные для отображения пользователю, никогда не должны анализироваться.Вы должны использовать классы.

Использовать осмысленные имена. Я знаю, что вы не очистили код, но если вы хотите, чтобы кто-то помог вам через Интернет, вы действительноshould.

Наконец, получите элемент по индексу. Если вы заглянули в документацию , вы бы заметили , есть свойство индексатора, которое получаетэлемент непосредственно по его индексу.

class EntryItem {
    public EntryItem (EventLogEntry entry) 
    {
        EntryIndex = entry.Index;
        ItemText = string.Format ("{0} - {1} - {2}     - {3}",
            entry.Index,
            entry.EntryType,
            entry.TimeWritten,
            entry.Source);
    }

    public string ItemText { get; private set; }
    public int EntryIndex { get; private set; }

    public override string ToString ()
    {
        return ItemText;
    }
}

private EventLog log = new EventLog {
    Log = "System"
};

private void eventLoader_DoWork (object sender, DoWorkEventArgs e)
{
    foreach (EventLogEntry entry in this.log.Entries)
        this.Dispatcher.BeginInvoke (() => eventListBox.Items.Add (new EntryItem (entry)));
}

private void eventListBox_SelectionChanged (object sender, SelectionChangedEventArgs e)
{
    EntryItem item = eventListBox.SelectedItem as EntryItem;
    if (item == null)
        return;

    var entry = log.Entries [item.EntryIndex];
    currentEntryLabel.Content = entry.Message;
}
...