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 auskenne 🙂

    Ja 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.


Anmelden zum Antworten