Получаване на подробности за събитие от регистъра на събитията

Опитвам се да получа подробности от регистъра на събитията въз основа на избора на елемент в списъчно поле. Опитвах се да поставя подробностите в текстово поле. Не успях да намеря решение сам. Това, което направих, и е изключително бавно, е повтаряне през регистъра на събитията и намиране на съвпадение с индекса на журнала, след което показване на съобщението, но това отнема много време. Има ли много по-бърз начин да стигнете директно до конкретния запис в дневника въз основа на индекса на дневника. Използвам 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 е това, което причинява увисването в потребителския интерфейс, но дори и да го настроя на друга нишка, както направих, докато добавях елементите към списъчното поле, пак ще отнеме известно време, за да премина през всичко, за да получа точен индекс търся. Така че това, което наистина искам да направя, е просто да отида направо до този индекс и да взема съобщението, вместо да обикалям целия списък, търсейки го.


person Rekar    schedule 13.06.2011    source източник
comment
Регистърът на събитията е предназначен за съхраняване на системни/приложни събития, които може да искате да прегледате по-късно (напр. при отстраняване на грешки или разследване на проблем). Всъщност не е предназначен за четене от приложение, напълно сигурни ли сте, че използвате правилния инструмент за проблема?   -  person Dan Abramov    schedule 13.06.2011
comment
Просто правя това като учебен опит. Връщам се в света на програмирането след известно време извън него. Така че, въпреки че не е предназначено да го правя, ще се опитам да го направя, само за да се науча. Не е предвидено по някаква конкретна причина.   -  person Rekar    schedule 13.06.2011
comment
Все пак не мога да разбера напълно въпроса ви. Какво има в списъка? Какво се съхранява в регистъра на събитията? Как елемент от списъчно поле съответства на елемент от регистър на събития? Кутията съдържа ли всички елементи? Покажете кода.   -  person Dan Abramov    schedule 13.06.2011
comment
Добавих кода, за да го разгледате. Не обръщайте внимание на бъркотията в него в момента, не съм почиствал или коментирал.   -  person Rekar    schedule 14.06.2011


Отговори (1)


След като разгледах кода ви, ето кратко резюме на това, което бих направил:

Премахване на манипулатора ProgressChanged. Той е предназначен за докладване на текущото състояние на потребителя, което вие не правите. Вместо това извикайте Items.Add в DoWork манипулатор.

Създайте EventLog веднъж. Това просто изглежда по-хубаво и ви спестява потенциалното създаване на циклично, ако не сте внимателни.

Вместо да анализирате текст с регулярен израз, създайте специален клас. Това е наистина важно и ще ви спести много болка, когато имате нужда от по-точно поведение или не желаете индекс на показване изобщо. Регулярните изрази са бавни и данните, предназначени за показване на потребителя, никога не трябва да се анализират. Трябва да използвате класове.

Използвайте смислени имена. Знам, че не сте изчистили кода, но ако искате някой да ви помогне по интернет, наистина трябва.

Накрая, вземете елемент по индекс. Ако сте разгледали документацията, ще имате забелязано има свойство на индексатор, което получава елемент директно чрез неговия индекс.

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;
}
person Dan Abramov    schedule 13.06.2011