2009-07-15 4 views
54

Ich versuche, in die Ereignisanzeige in meinem C# -Code zu schreiben, aber ich bekomme die wundervolle "Objektreferenz nicht auf eine Instanz eines Objekts gesetzt". Ich würde eine Hilfe mit diesem Code schätzen, entweder was falsch ist oder sogar eine bessere Art, es zu tun. Hier ist, was ich für in das Ereignisprotokoll zu schreiben:C# Schreiben in die Ereignisanzeige

private void WriteToEventLog(string message) 
{ 
    string cs = "QualityDocHandler"; 
    EventLog elog = new EventLog(); 
    if (!EventLog.SourceExists(cs)) 
    { 
     EventLog.CreateEventSource(cs, cs); 
    } 
    elog.Source = cs; 
    elog.EnableRaisingEvents = true; 
    elog.WriteEntry(message); 
} 

Und hier ist, wo ich versuche, es zu nennen:

private readonly Random _rng = new Random(); 
private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
private string RandomString(int size) 
{ 
    try 
    { 
     char[] buffer = new char[size]; 
     for (int i = 0; i < size; i++) 
     { 
      buffer[i] = _chars[_rng.Next(_chars.Length)]; 
     } 
     return new string(buffer); 
    } 
    catch (Exception e) 
    { 
     WriteToEventLog(e.ToString()); 
     return null; 
    } 
} 
+0

In welcher Zeile ist der Fehler an? – NikolaiDante

+0

Bitte geben Sie einen Stack-Trace –

+1

"Objektverweis nicht auf eine Instanz eines Objekts festgelegt" - bedeutet, dass Sie eine NULL verweisen, ist es viel hilfreicher, die Codezeile zu wissen, wo dies geschieht, denn dann können Sie sehen, was es ist ist das NULL, auf das du dich beziehst. –

Antwort

87

Das Problem ist wahrscheinlich dass Sie versuchen, eine Ereignisquelle in einem Protokoll zu erstellen, das nicht vorhanden ist. Sie müssen das Protokoll "Anwendung" angeben.

Versuchen Sie es zu ändern:

if (!EventLog.SourceExists(cs)) 
    EventLog.CreateEventSource(cs, "Application");  

EventLog.WriteEntry(cs, message, EventLogEntryType.Error); 

auch: Innerhalb von Sharepoint, wenn die App als angemeldeten Benutzers ausgeführt wird (via Windows-Auth oder eine Delegation), wird der Benutzer keinen Zugriff haben das Ereignis erstellen Quelle. Wenn dies der Fall ist, besteht ein Trick darin, das Ereignis mithilfe eines ThreadPool-Threads zu erstellen, bei dessen Erstellung der Sicherheitskontext des Benutzers angezeigt wird, unter dem der App-Pool ausgeführt wird.

22

Hier ist, wie ich Ereignisprotokollierung implementiert. Ich habe eine generische Schnittstelle ILogger so dass ich in verschiedenen Logging-Mechanismen austauschen können:

interface ILogger 
{ 
    void Debug(string text); 

    void Warn(string text); 

    void Error(string text); 
    void Error(string text, Exception ex); 
} 

Meine Implementierungsklasse ist sehr einfach:

class EventLogger : ILogger 
{ 
    public void Debug(string text) 
    { 
     EventLog.WriteEntry("MyAppName", text, EventLogEntryType.Information); 
    } 

    public void Warn(string text) 
    { 
     EventLog.WriteEntry("MyAppName", text, EventLogEntryType.Warning); 
    } 

    public void Error(string text) 
    { 
     EventLog.WriteEntry("MyAppName", text, EventLogEntryType.Error); 
    } 

    public void Error(string text, Exception ex) 
    { 
     Error(text); 
     Error(ex.StackTrace); 
    } 
} 

Bitte beachte, dass ich EventLog nicht instanziiert. Zu meiner Logger-Klasse zu verwenden, ich habe nur den folgenden Hinweis (Sie könnte dies durch eine statische Factory-Methode zurück):

private static readonly ILogger log = new EventLogger(); 

Und die tatsächliche Nutzung ist wie folgt:

try 
{ 
    // business logic 
} 
catch (Exception ex) 
{ 
    log.Error("Exception in MyMethodName()", ex); 
} 
+11

das ist gut, aber es hat nichts mit seiner eigentlichen Frage zu tun o.O –

+8

True, aber ich habe keinen StackTrace von arbeiten. – Nelson

+0

Dies hätte die Frage beantwortet, wenn Sie in den Standardkonstruktor 'if (! EventLog.SourceExists (source))' hinzugefügt hätten, um zu überprüfen, ob es existiert, und eine 'const string source', die Sie in code (oder via prop oder contrector override) und durch die gesamte Klasse wiederverwenden.Jedes Mal, wenn Sie die EventLogger-Klasse instanziieren, stellt sie sicher, dass der tatsächliche Fehler, den das OP erfahren hat, nicht passieren wird. Ich habe diesen Code in Kombination mit der akzeptierten Antwort verwendet. +1 – ppumkin

1
private void WriteEventLogToFile() 
    { 
     try 
     { 
      using (EventLog eventLog = new EventLog("Application")) 
      { 
      // source for your event 
       eventLog.Source = "IAStorDataMgrSvc"; 

      // Syntax details 
      // eventLog.WriteEntry("details",type of event,event id); 
      eventLog.WriteEntry("Hard disk Failure details", EventLogEntryType.Information, 11); 
      } 
     } 
     catch (Exception) 
     { 
      throw; 
     } 
    }