C# event Problem
-
Hallo,
Ich habe ein Problem mit ein Event, und zwar wird es nicht ausgelöst nach ankommende Nachrichten!
Komischerweise hat das aber alles mal Funktioniert, da ich nur die klasse übernommen habe, die ich damals gemacht habe!Es geht darum:
Das Event soll ausgelöst werden, wenn über Socket was rein kommt, damit ich damit weiter arbeiten kann.
Der Fehler ist der, das beim ersten mal er nicht ins Event geht, und bei der 2ten Nachricht er es macht, bloß warum erst nach dem 2ten mal?Klasse - DLL
namespace Netzwerk { public delegate void MyHandler(string Message); public class Netzwerkdll { // Event public static event MyHandler MyEvent; // Background Instance static BackgroundWorker bgwnetz = new BackgroundWorker(); // Socket - IPENDP Instance private static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); static IPEndPoint IPENDP = new IPEndPoint(IPAddress.Parse("25.174.181.80"), 3000); // Variabeln // Hier werden die ergebnisse gespeichert von Sockets private static string ergebnis; // Schalter Socket public static bool socketschalter() { return socket.Connected; } // Socket-Connect Start Backgroungworker public static void socketconnect() { socket.Connect(IPENDP); backgroundworkerstart(); } public static void backgroundworkerstart() { bgwnetz.DoWork += new DoWorkEventHandler(bgwnetz_DoWork); bgwnetz.WorkerSupportsCancellation = true; bgwnetz.RunWorkerAsync(); } // Backgroundworker public static void bgwnetz_DoWork(object sender, DoWorkEventArgs e) { // Buffer für ankommende Nachrichten byte[] buffE = new byte[1024]; while (true) { MyHandler myEvent = MyEvent; // Rufe werte ab if (socketschalter()) { try { // Erstelle RecByte int RecByte = socket.Receive(buffE); // Wandel werte in String um ergebnis = ASCIIEncoding.ASCII.GetString(buffE, 0, RecByte); if (myEvent != null) { myEvent(ergebnis); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } else { break; } } } // Socket-send-text public static void sendesocket(string sende) { byte[] buffer = ASCIIEncoding.ASCII.GetBytes(sende); socket.Send(buffer); Array.Clear(buffer, 0, buffer.Length); } // Socket schließen public static void closesocket() { socket.Close(); bgwnetz.CancelAsync(); bgwnetz.DoWork -= new DoWorkEventHandler(bgwnetz_DoWork); } } }
Und hier die Message Funktion vom Event:
Login Form:private void frmLogin_Load(object sender, EventArgs e) { Netzwerkdll.MyEvent += new MyHandler(Message); } private void Message(string e) { // Hier will ich die Daten bekommen, die erst nach dem 2ten mal ankommen! }
Und oben ignoeriert er halt beim ersten mal die if abfrage bzw sagt das Event noch null ist!
if (myEvent != null) { myEvent(ergebnis); }
Könnt ihr mir vielweicht sagen, warum das Event beim ersten mal noch null ist? und das vor 5 Monaten im anderen Projekt geklappt hat?
Gruß
-
Wann rufst du denn backgroundworkerstart() auf?
Bedenke, daß dieser in einem eigenen Thread läuft und daher die Eventmethode mit dem GUI-Thread synchronisiert werden muß (sofern du dann GUI-Controls ansprichst).
Gerade dafür gibt es aber beim BackgroundWorker das ProgressChanged-Ereignis, welches im GUI-Thread läuft, so daß man nicht selber für die Synchronisierung (z.B. mittels Control.Invoke) sorgen muß.
Wenn du doch ein eigenes Event haben willst, dann lass es wenigstens im ProgressChanged-Ereignis auslösen!
PS: Die ganze Klasse mit statischen Methoden auszustatten, zeigt auch nicht gerade für ein gutes Design
Und noch ein PPS: eigene Events solltest du mittels
public event EventHandler MyEvent; // bzw. public event EventHandler<MyEventArgs> MyEvent;
deklarieren (um dich an den Standard zu halten).
-
Hallo,
Der Backgroundworker wird bei einer form aufgerufen im load Ereignis!
Die form wird nach der ganzen inizialisierung beendet, wo er auch gleichzeitig mit dem Server erstmals connectet.
Ist das so falsch?
Ich bin kein großer könner in der geschichte, da ich mit C angefangen habe, und mich mit den Klassen noch 0 auskenneJa aber warum er das beim ersten mal nicht macht kann ich echt nicht nachvollziehen
liegt das Problem eventuell an der ersten form die dann auch geschlossen wird automatisch?
-
Weißt du überhaupt wie Threads funktionieren?
In deinem Fall wird es so sein, daß eben zuerst die Backgroundworker-Schleife einmalig abgearbeitet wird, ehe die Eventmethode abonniert wird.
Achte also auf die Reihenfolge:Netzwerkdll.MyEvent += new MyHandler(Message); Netzwerkdll.backgroundworkerstart();
Aber wenn die Form danach beendet wird, was machst du dann in der Eventmethode 'Message' - und warum befindet sich diese Methode dann in der Form-Klasse?
Du solltest dich dann aber mal grundlegend einlesen, z.B. [Artikel] Multi-Threaded Programmierung.
-
ahh ich verstehe.
Ja im anderen projekt ging es nämlich ohne Probleme, da denke ich mal das du mit den schleifen durchlauf recht hast, das die erste Nachricht nicht auf das Event anspringt.Die message funktion ist in der frmLogin, die auch immer offen bleibt.
Also die Reihenfolge sieht so aus:1. wird die start form geöffnet, wo ich meine Klassen etc.. und den socket wie backgroundworker starte.
Wenn das fertig ist, schließt die form und es geht die Login form auf, wo beim loadereignis das Event gestartet wird.Also muss ich das mit dem Event auch in der start form machen? also bevor ich das mit dem socket etc.. mache?
*Ja ich habe mir schon einiges angeguckt, daher versuche ich auch schon was ja fast funktioniert
PS:
Wo es funktioniert hat, öffnet sich nur eine form, wo ich alles mache, und da sieht es so aus (Was auch funktioniert hat)!private void frmLogin_Load(object sender, EventArgs e) { Netzwerkdll.MyEvent += new MyHandler(Message); try { Netzwerkdll.socketconnect(); this.btnlogin.Enabled = true; this.btnregelogin.Enabled = true; this.lblloginserverstatus.Text = "Server ist Online!"; this.lblloginserverstatus.ForeColor = System.Drawing.Color.Green; } catch (Exception ex) { this.btnlogin.Enabled = false; this.btnregelogin.Enabled = false; this.lblloginserverstatus.Text = "Server ist Offline!"; this.lblloginserverstatus.ForeColor = System.Drawing.Color.Red; } }
-
Habe es mal getestet und jetzt geht es
Danke für deinen Hinweis.