Hallo zusammen,
ich habe eine Frage zu Events und hoffe, dass ihr mir weiterhelfen könnt. Ich muss auch dazu schreiben, dass ich mich erst seit kurzem mit C# befasse.
Ich habe nach dieser Anleitung einen Event programmiert ([Lösung] Problem mit EventHandler [==> fertige Code-Snippets inkl. Erklärung]) und das funktioniert auch soweit. Die event-auslösende Methode informiert den Eventhandler. Jetzt möchte ich aber auch aus einer anderen Klasse ein Event auslösen und der Eventhandler soll entsprechend reagieren. Leider klappt das nicht so, wie ich es mir vorstelle. Nachfolgend mein Code:
Klasse LogFile mit der event-auslösende Methode: Es soll nur einfache Textinformationen loggen.
class LogFile
{
//Event for log file change
public event EventHandler LogEvent;
protected virtual void MyLogEvent(EventArgs e)
{
EventHandler logEvent = LogEvent;
if (logEvent != null)
{
logEvent(this, e);
}
}
//Set list for text information and define counter
private static List<string> LogSum = new List<string>();
private static int count = 1;
//After each call log file will be added and index increased
public void AddLogFile (string logText)
{
//Log number and text information
LogSum.Add(count + ": " + logText);
count++;
//Activate event
MyLogEvent(EventArgs.Empty);
}
public List<string> GetLogFile()
{
return LogSum;
}
}
Klasse MainForm mit dem Eventhandler: Die Log Informationen sollen hier vereinfacht in einer Textbox dargestellt weden.
public partial class MainForm : Form
{
LogFile _log = new LogFile();
Control _control;
public static List<string> LogFiles = new List<string>();
public MainForm()
{
InitializeComponent();
_log.LogEvent += LogChanged;
}
private void btnStart_Click(object sender, EventArgs e)
{
//do something
_log.AddLogFile("Something made: 1");
_control = new Control();
}
//Update log view
public void LogChanged(object sender, EventArgs e)
{
//Get new log file
LogFiles = _log.GetLogFile();
//Write down to textbox
TestTextBox.Text = null;
foreach (string item in LogFiles)
{
TestTextBox.Text += item + "\r\n";
}
TestTextBox.Refresh();
}
}
Soweit funktioniert alles und „Something made: 1“ steht in der Textbox. Nachfolgend eine andere Klasse, der ebenfalls ein Logeintrag durchführt und somit ebenfalls ein Event auslösen soll.
class Control
{
LogFile _log = new LogFile();
public Control()
{
//do something
_log.AddLogFile("Something made: 2");
}
}
In meiner Testtextbox steht trotzdem nur der erste Eintrag „Something made: 1“. Der zweite Eintrag kommt nicht, weil in der event-auslösenden Methode logEvent = null ist.
Warum steht bei logEvent beim Aufruf über eine andere Klasse null? Die Textinformation wird auf jeden Fall geloggt und ist vorhanden. Sie löst nur kein Event aus.
Vielen Dank für eure Tipps im voraus.
Hi,
das ist recht einfach erklärt - aktuell besitzt du mit deinem Code 2 Instanzen der Klasse "LogFile" wo du nur eine bräuchtest.
Die erste wird in deiner Form erzeugt und an deren Event hängst du dich ran.
Die zweite wird im Control erzeugt - deren Event abonnierst du allerdings nirgends - deswegen kommt auch nirgends ein Event an.
Die einfachste Variante um das zu lösen wäre es wohl bei der Instanziierung der Klasse Control (control = new Control();) eine Referenz auf die Instanz der Klasse LogFile mitzugeben. (also: control = new Control(_log);)
LG
Noch einige Anmerkungen:
a) Logging sollte/muss man heute nicht mehr selbst bauen. Was immer du tust - gibt es schon fertig und besser. Serilog, NLog und zig andere Frameworks die auch entsprechende Standardschnittstellen bieten sind hier einen Blick wert
b) Deinen Code für das EventHandling solltest du noch mal anpassen.
protected virtual void OnLogEntryAdded(EventArgs e)
{
LogEvent?.Invoke(this, e);
}
Du hast zwei Instanzen Deines Loggings.
PS:
Gibt 2019 keine große Notwendigkeit ein Loggingmechanismus selbst zu schreiben.
In .NET ist das absolute führende Framework hierzu serilog, das in allen Arten von .NET Applikation binnen weniger Minuten aufgesetzt ist.
/ Taipi88 war schneller.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code