Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

EventHanlder Crash

Îåêßíçóå áðü ôï ìÝëïò g1024. Τελευταία δημοσίευση από το μέλος g1024 στις 13-12-2010, 10:39. Υπάρχουν 3 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  12-12-2010, 17:01 61535

    EventHanlder Crash

    Καλησπέρα σας.
    Προσπαθώ να φτιάξω μία Κλάση σε C# όπου θα μπορώ σε μελλοντικά μου Projects να την κάνω Instanse και να παίρνω μεσώ Δικτύου κάποια δεδομένα απο ένα μηχάνημα.
    Εχω δημιουργησει ένα Event για να "λεέι" στην φόρμα (απ' οπου θα κάνω instanse την κλάση) ότι ήρθαν δεδομένα.Παραθέτω τον κώδικα της κλάσης και της φόρμας.

    ΚΛΑΣΗ....
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Windows.Forms;


    namespace Telemanager
    {
        public enum ConnectionType //Ο τύπος της σύνδεσης (Serial ή Network)
        {
            Serial,
            NetWork
        }
        public delegate void gotData();

        class PbxCon
        {
                                                                  
            private Socket client;                                                  // To Socket
            private byte[] data = new byte[1024];                                   // Τα Δεδομένα Πρός αποστολή.
            private int size = 1024;                                                // Το μέγεθος του Buffer.
            public string stringData = "";                                          // Τα εισερχόμενα Δεδομένα.
           

            Socket newSocket = new Socket(AddressFamily.InterNetwork,               // Δημιουργούμε ένα νέο Socket Με πρωτόκολλο TCP και
                 SocketType.Stream, ProtocolType.Tcp);                              // για ανταλλαγή δεδομένων ροής.

            public event gotData tcpStream;                                         // Αυτό το Event θα καλείτε για να κάνει fire triger ότι ήρθαν δεδομένα.

            public PbxCon(string Host, int tcpPort)                                 // Η μέθοδος όπου ξεκινά η σύνδεση του με τον Host.
            {
                newSocket.BeginConnect(Host, tcpPort, new AsyncCallback(Connected), newSocket);         // Δημιουργία ασύγχρωνης επικοινωνίας με τον Host όπου για την κατάσταση της σύνδεσης
            }                                                                                           // θα μας τα στείλει στην μέθοδο Connected.

            private void Connected(IAsyncResult iar)
            {
                client = (Socket)iar.AsyncState;
                try
                {
                    client.EndConnect(iar);
                   // MessageBox.Show("Connected to: " + client.RemoteEndPoint.ToString());
                    client.BeginReceive(data, 0, size, SocketFlags.None,
                                  new AsyncCallback(ReceiveData), client);
                }
                catch (SocketException)
                {
                    MessageBox.Show("Error connecting");
                }
            }


            private void ReceiveData(IAsyncResult iar)
            {
               // MessageBox.Show("We Have Data!");
                Socket remote = (Socket)iar.AsyncState;
                int recv = remote.EndReceive(iar);
                if (recv > 1)
                {
                    stringData += Encoding.ASCII.GetString(data, 0, recv);
                    client.BeginReceive(data, 0, size, SocketFlags.None,
                                   new AsyncCallback(ReceiveData), client);
                    remote.EndReceive(iar);
                    tcpStream();

                }

            }
            private void SendData(IAsyncResult iar)
            {
                Socket remote = (Socket)iar.AsyncState;
                int sent = remote.EndSend(iar);
                remote.BeginReceive(data, 0, size, SocketFlags.None,
                              new AsyncCallback(ReceiveData), remote);
            }
            public void Send(string n)
            {
                byte[] message = Encoding.ASCII.GetBytes(n);
                client.BeginSend(message, 0, message.Length, SocketFlags.None,
                             new AsyncCallback(SendData), client);
            }
        }
     
    }

    ΦΟΡΜΑ....
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;

    namespace Telemanager
    {
        public partial class Form1 : Form
        {
            private PbxCon n;

            public Form1()
            {
                InitializeComponent();
                n = new PbxCon("127.0.0.1", 5100);
                n.tcpStream += new gotData(n_Message);
            }
           
            private void button1_Click(object sender, EventArgs e)
            {
                textBox1.Text = n.stringData;
            }

            public void n_Message()
            {
              textBox1.Text = n.stringData;
            }

        }
    }


    Το πρόβλημα μου έιναι το εξής ,όταν γίνεται Fire το Event tcpStream κλεινει η εφαρμογή μου (χωρίς να κλείσει το IDE του Visual Studio) χωρίς κανένα μηνυμα λάθους, αν βγάλω το textBox1.Text = n.stringDataκαι βάλω τα δεδομένα να εμφανιστούν σε ένα MessageBox δουλέυει κακονικά!!!
    Καμια ιδέα;

    Ευχαριστώ.

  •  12-12-2010, 19:07 61537 σε απάντηση της 61535

    Απ: EventHanlder Crash

    g1024:
    Καλησπέρα σας.
    Προσπαθώ να φτιάξω μία Κλάση σε C# όπου θα μπορώ σε μελλοντικά μου Projects να την κάνω Instanse και να παίρνω μεσώ Δικτύου κάποια δεδομένα απο ένα μηχάνημα.
    Εχω δημιουργησει ένα Event για να "λεέι" στην φόρμα (απ' οπου θα κάνω instanse την κλάση) ότι ήρθαν δεδομένα.Παραθέτω τον κώδικα της κλάσης και της φόρμας.

    ΚΛΑΣΗ....
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.Windows.Forms;


    namespace Telemanager
    {
        public enum ConnectionType //Ο τύπος της σύνδεσης (Serial ή Network)
        {
            Serial,
            NetWork
        }
        public delegate void gotData();

        class PbxCon
        {
                                                                  
            private Socket client;                                                  // To Socket
            private byte[] data = new byte[1024];                                   // Τα Δεδομένα Πρός αποστολή.
            private int size = 1024;                                                // Το μέγεθος του Buffer.
            public string stringData = "";                                          // Τα εισερχόμενα Δεδομένα.
           

            Socket newSocket = new Socket(AddressFamily.InterNetwork,               // Δημιουργούμε ένα νέο Socket Με πρωτόκολλο TCP και
                 SocketType.Stream, ProtocolType.Tcp);                              // για ανταλλαγή δεδομένων ροής.

            public event gotData tcpStream;                                         // Αυτό το Event θα καλείτε για να κάνει fire triger ότι ήρθαν δεδομένα.

            public PbxCon(string Host, int tcpPort)                                 // Η μέθοδος όπου ξεκινά η σύνδεση του με τον Host.
            {
                newSocket.BeginConnect(Host, tcpPort, new AsyncCallback(Connected), newSocket);         // Δημιουργία ασύγχρωνης επικοινωνίας με τον Host όπου για την κατάσταση της σύνδεσης
            }                                                                                           // θα μας τα στείλει στην μέθοδο Connected.

            private void Connected(IAsyncResult iar)
            {
                client = (Socket)iar.AsyncState;
                try
                {
                    client.EndConnect(iar);
                   // MessageBox.Show("Connected to: " + client.RemoteEndPoint.ToString());
                    client.BeginReceive(data, 0, size, SocketFlags.None,
                                  new AsyncCallback(ReceiveData), client);
                }
                catch (SocketException)
                {
                    MessageBox.Show("Error connecting");
                }
            }


            private void ReceiveData(IAsyncResult iar)
            {
               // MessageBox.Show("We Have Data!");
                Socket remote = (Socket)iar.AsyncState;
                int recv = remote.EndReceive(iar);
                if (recv > 1)
                {
                    stringData += Encoding.ASCII.GetString(data, 0, recv);
                    client.BeginReceive(data, 0, size, SocketFlags.None,
                                   new AsyncCallback(ReceiveData), client);
                    remote.EndReceive(iar);
                    Thread thNew = new Thread(new ThreadStart(houstonWeHaveData));
                    thNew.Start();

                }

                }
            }
            private void houstonWeHaveData()
            {
                tcpStream();
            }


            }
            private void SendData(IAsyncResult iar)
            {
                Socket remote = (Socket)iar.AsyncState;
                int sent = remote.EndSend(iar);
                remote.BeginReceive(data, 0, size, SocketFlags.None,
                              new AsyncCallback(ReceiveData), remote);
            }
            public void Send(string n)
            {
                byte[] message = Encoding.ASCII.GetBytes(n);
                client.BeginSend(message, 0, message.Length, SocketFlags.None,
                             new AsyncCallback(SendData), client);
            }
        }
     
    }

    ΦΟΡΜΑ....
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net;
    using System.Net.Sockets;

    namespace Telemanager
    {
        public partial class Form1 : Form
        {
            private PbxCon n;

            public Form1()
            {
                InitializeComponent();
                n = new PbxCon("127.0.0.1", 5100);
                n.tcpStream += new gotData(n_Message);
            }
           
            private void button1_Click(object sender, EventArgs e)
            {
                textBox1.Text = n.stringData;
            }

            public void n_Message()
            {
              textBox1.Text = n.stringData;
            }

        }
    }


    Το πρόβλημα μου έιναι το εξής ,όταν γίνεται Fire το Event tcpStream κλεινει η εφαρμογή μου (χωρίς να κλείσει το IDE του Visual Studio) χωρίς κανένα μηνυμα λάθους, αν βγάλω το textBox1.Text = n.stringDataκαι βάλω τα δεδομένα να εμφανιστούν σε ένα MessageBox δουλέυει κακονικά!!!
    Καμια ιδέα;

    Ευχαριστώ.





    Μετα κόπον και βασάνον πρόσθεσα τον παραπάνω κώδικα και έστρωσε!
    Ευχαριστώ.
  •  13-12-2010, 10:12 61541 σε απάντηση της 61537

    Απ: EventHanlder Crash

    Δεν μπορώ να καταλάβω ακριβώς την αλλαγή που έκανες αλλά έχω 2-3 πράγματα να προσθέσω:

    1. Καλό είναι να μην έχεις MessageBox.Show στον κώδικα της κλάσης σου γιατί έτσι δημιουργείς dependency στο System.Windows και δεν θα μπορείς να την χρησιμοποιήσεις σε κάποιο κώδικα που δεν το έχεις. π.χ. σε κάποιο Windows Service ή ASP.NET.
    2. Όταν έχουμε κλάσεις που κάνουν πράγματα ασύχρονα όπως η δική σου, συνηθίζεται να χειριζόμαστε με δυο τρόπους τα exceptions που μπορεί να συμβούν σε αυτή:
      1. Περνάμε το instance ενός logger στην αρχικοποίησή της για να μπορεί να γράφει τα exceptions που συμβαίνουν. π.χ. μπορείς να κάνεις ένα interface ILogger που να έχει μια void Write(string text) και να υλοποιείς το interface στη φόρμα σου. Ο constructor της κλάσης σου θα έχει μια παράμετρο _ctor(ILogger logger) και εκεί θα παιρνάς το instance της φόρμας.
      2. Προσθέτουμε ένα ακόμα event που λέγεται Error(object sender, EventArgs<Exception> args) το οποίο γίνεται trigger από την κλάση κάθε φορά που συμβαίνει κάτι κακό και το πιάνει η φόρμα
    3. Καλό είναι το n.stringData να είναι μέρος του event Message και να μην το διαβάζεις από το property. Διαφορετικά αν γίνει trigger το event σου παραπάνω από μια φορά πολύ γρήγορα τότε κινδυνεύεις να διαβάσεις τα δεδομένα της τελευταίας φοράς για όλα τα triggers.

    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  13-12-2010, 10:39 61544 σε απάντηση της 61541

    Απ: EventHanlder Crash

    Για να είμαι ειλικρινής το πρόγραμμα "έσκασε" πάλι.
    το 1 και το 3 το κατάλαβα απόλυτα το 2 σε έχασα.Δυστηχώς δεν έχω καταλαβει πως δουλευουν τα interface.Αλλα μία και μου έδωσες την ιδέα θα προσπαθήσω να βρώ κάτι απο το web να διαβάσω.
    Ευχαριστώ πάντος.(αν έχεις κάποιο έτοιμο κείμενο για τα interface καλοδεχούμενο)
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems