Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 4 von 4

Thema: TwinCAT ADS in C# Applikation frisst den Arbeitsspeicher auf

  1. #1
    Registriert seit
    18.12.2009
    Beiträge
    8
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo

    Ich habe ein Programm in C# mit WPF Oberfläche geschrieben welches im Hintergrund mit der "TwinCAT.Ads.dll" von Beckhoff arbeitet.

    Zur abfrage meiner Variablen nutze ich die DeviceNotification Funktion, in der ich das Zeitlimit für das Abfragen auf 250 ms gestellt habe.
    Zu überwachen sind 26 Variablen vom Typ BOOL, DINT oder LREAL (insgesamt 93 Bytes).


    Code:
    private int Zyklus_VarRefresh = 250;    //Zykluszeit zum Erneuern der SPS Werte
    
    private TcAdsClient tcClient; //ADS Client
    
    private static AdsStream adsreaderStream = new AdsStream(93); //ADS Stream zum Zyklischen Abfragen aller Variablen
    private static BinaryReader binReader = new BinaryReader(adsreaderStream); //Reader für ADS Stream zum Zyklischen Abfragen aller Variablen
    
    ...
    
    Handle_GlobalVar1 = tcClient.AddDeviceNotification(".GlobalVar1", adsreaderStream, 0, 4, AdsTransMode.OnChange, Zyklus_VarRefresh, 0, DBNull.Value); //4 Bytes
    Handle_GlobalVar2 = tcClient.AddDeviceNotification(".GlobalVar2", adsreaderStream, 4, 4, AdsTransMode.OnChange, Zyklus_VarRefresh, 0, DBNull.Value); //4 Bytes
    ...
    
    tcClient.Synchronize = true;
    tcClient.AdsNotification += new AdsNotificationEventHandler(tcClient_AdsNotification);
    Ändert sich ein Variablenwert wird das Event aufgerufen:

    Code:
    void tcClient_AdsNotification(object sender, AdsNotificationEventArgs e)
    {
            e.DataStream.Position = e.Offset;
    
            switch (e.NotificationHandle)
            {
                //GlobalVar1
                case 1: 
                    ...

    Dies funktioniert eigendlich ganz gut.... bis das Programm irgendwann abstürtzt weil es mehr wie 1 GB Arbeitsspeicher reserviert hat

    Ist eine Verbindung aufgebaut, werden in meinem Code keine neuen Variablen Deklariert, kein Array gefüllt usw.
    Trotzdem steigt der Speicher stetig an.

    Die einzige alternative die mir einfällt ist jede Variable einzeln zu pollen.

    Kennt jemand das Problem oder hat einen Tipp was ich da machen kann.


    Gruß
    Stefan
    Zitieren Zitieren TwinCAT ADS in C# Applikation frisst den Arbeitsspeicher auf  

  2. #2
    Registriert seit
    24.04.2008
    Ort
    Lübeck
    Beiträge
    324
    Danke
    8
    Erhielt 63 Danke für 62 Beiträge

    Standard

    Code:
    void tcClient_AdsNotification(object sender, AdsNotificationEventArgs e) {
             e.DataStream.Position = e.Offset;
              switch (e.NotificationHandle)
             {
                 //GlobalVar1
                 case Handle_GlobalVar1:
                      ...
    Müsste hier in der Case-Anweisung nicht das Handle abgefragt werden?

    Ich habe auch schon häufig Notifications genutzt, aber nie eine solche Speicherauslastung bemerkt.
    Derzeit kann ich im Code jedoch keinen groben Fehler erkennen. Nach welcher Zeit tritt denn der Absturz auf?
    Könntest du eventuell noch den restlichen Code vom Notification-Handler (tcClient_AdsNotification) posten?

  3. #3
    sparx ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    18.12.2009
    Beiträge
    8
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Ja das Handle muss abgefragt werden.
    In C# werden bei switch case nur Konstante Werte zugelassen. Bei Visual Basic gibt es select case wo als Sprungmarke eine Variable erlaubt ist.
    Ich könnte das switch duch mehrere if Anweisungen ersetzen in denen ich die "Handle_*" Variablen abfrage.
    Da ich aber die Reihenfolge weiß in denen ich die Variablen für das Event registriere, kann ich da mit festen Nummern arbeiten.

    Ich habe jetzt einfach mal die ganze Methode kopiert.
    Im Beispiel meines letzten Posts habe ich die Ersten Vaiablen vom Namen angepasst, also nicht wundern.

    Das Programm in dem ich diesen Code nutze soll mehrere Tage durchlaufen. Nach 2 - 3 Tagen laufzeit ist der Verwendete Arbeitsspeicher bei 1GB!
    Könnte es vieleicht sein das 250ms abfragezeit zu schnell ist?

    Code:
     void tcClient_AdsNotification(object sender, AdsNotificationEventArgs e)
            {
                e.DataStream.Position = e.Offset;
    
                switch (e.NotificationHandle)
                {
                    //SPS_Temp_Kanal1
                    case 1: 
                        SPS_Temp_Kanal1 = binReader.ReadInt32();
    
                        if (SPS_Temp_Kanal1 > 80000)
                        {
                            //Wenn Temperatur größer 800°C -> Kein Messelement angeschlossen
                            tb_sps_temp_knl1.Text = "----------";
                        }
                        else
                        {
                            //Temperaturwert durch 100 Teilen und anzeigen
                            tb_sps_temp_knl1.Text = (Convert.ToDouble(SPS_Temp_Kanal1.ToString()) / 100).ToString();
                        }
                        break;
    
                    //SPS_Temp_Kanal2
                    case 2:
                        SPS_Temp_Kanal2 = binReader.ReadInt32();
    
                        if (SPS_Temp_Kanal2 > 80000)
                        {
                            //Wenn Temperatur größer 800°C -> Kein Messelement angeschlossen
                            tb_sps_temp_knl2.Text = "----------";
                        }
                        else
                        {
                            //Temperaturwert durch 100 Teilen und anzeigen
                            tb_sps_temp_knl2.Text = (Convert.ToDouble(SPS_Temp_Kanal2.ToString()) / 100).ToString();
                        }
                        break;
    
                    //SPS_Temp_Kanal3
                    case 3:
                        SPS_Temp_Kanal3 = binReader.ReadInt32();
    
                        if (SPS_Temp_Kanal3 > 80000)
                        {
                            //Wenn Temperatur größer 800°C -> Kein Messelement angeschlossen
                            tb_sps_temp_knl3.Text = "----------";
                        }
                        else
                        {
                            //Temperaturwert durch 100 Teilen und anzeigen
                            tb_sps_temp_knl3.Text = (Convert.ToDouble(SPS_Temp_Kanal3.ToString()) / 100).ToString();
                        }
                        break;
    
                    //SPS_Temp_Kanal4
                    case 4:
                        SPS_Temp_Kanal4 = binReader.ReadInt32();
    
                        if (SPS_Temp_Kanal4 > 80000)
                        {
                            //Wenn Temperatur größer 800°C -> Kein Messelement angeschlossen
                            tb_sps_temp_knl4.Text = "----------";
                        }
                        else
                        {
                            //Temperaturwert durch 100 Teilen und anzeigen
                            tb_sps_temp_knl4.Text = (Convert.ToDouble(SPS_Temp_Kanal4.ToString()) / 100).ToString();
                        }
                        break;
    
                    //SPS_Servo_Betr_Winkel_IST
                    case 5:
                        SPS_Servo_Betr_Winkel_IST = binReader.ReadDouble();
    
                        //Wert Negieren und mit 3 Nachkommastellen anzeigen
                        tb_sps_servo_betr_w_ist.Text = (SPS_Servo_Betr_Winkel_IST * -1).ToString("0.000");
                        break;
    
                    //SPS_Servo_Betr_Winkel_SOLL
                    case 6:
                        SPS_Servo_Betr_Winkel_SOLL = binReader.ReadDouble();
    
                        //Wenn das Programm nicht im Handmodus ist auch die SollWerte anzeigen (Keine Manuelle Sollwerteingabe)
                        if (Programmstatus != Progstatus.Hand_Modus)
                        {
                            //Wert Negieren und mit 3 Nachkommastellen anzeigen
                            tb_sps_servo_betr_w_soll.Text = (SPS_Servo_Betr_Winkel_SOLL * -1).ToString("0.000");
                        }
                        break;
    
                    //SPS_Servo_Temp_Winkel_IST
                    case 7:
                        SPS_Servo_Temp_Winkel_IST = binReader.ReadDouble();
    
                        //Wert Negieren und mit 3 Nachkommastellen anzeigen
                        tb_sps_servo_temp_w_ist.Text = (SPS_Servo_Temp_Winkel_IST * -1).ToString("0.000");
                        break;
    
                    //SPS_Servo_Temp_Winkel_SOLL
                    case 8:
                        SPS_Servo_Temp_Winkel_SOLL = binReader.ReadDouble();
    
                        //Wenn das Programm nicht im Handmodus ist auch die SollWerte anzeigen (Keine Manuelle Sollwerteingabe)
                        if (Programmstatus != Progstatus.Hand_Modus)
                        {
                            //Wert Negieren und mit 3 Nachkommastellen anzeigen
                            tb_sps_servo_temp_w_soll.Text = (SPS_Servo_Temp_Winkel_SOLL * -1).ToString("0.000");
                        }
                        break;
    
                    //SPS_Servo_Tuer_offen_IST
                    case 9:
                        SPS_Servo_Tuer_offen_IST = binReader.ReadBoolean();
    
                        cb_sps_servo_tuer_auf_ist.IsChecked = SPS_Servo_Tuer_offen_IST;
                        break;
    
                    //SPS_Servo_Tuer_geschlossen_IST
                    case 10:
                        SPS_Servo_Tuer_geschlossen_IST = binReader.ReadBoolean();
    
                        cb_sps_servo_tuer_zu_ist.IsChecked = SPS_Servo_Tuer_geschlossen_IST;
                        break;

  4. #4
    sparx ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    18.12.2009
    Beiträge
    8
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Teil 2 des Codes:

    Code:
     //SPS_Servo_Tuer_offen_SOLL
                    case 11:
                        SPS_Servo_Tuer_offen_SOLL = binReader.ReadBoolean();
    
                        cb_sps_servo_tuer_auf_soll.IsChecked = SPS_Servo_Tuer_offen_SOLL;
                        break;
    
                    //SPS_Servo_Tuer_geschlossen_SOLL
                    case 12:
                        SPS_Servo_Tuer_geschlossen_SOLL = binReader.ReadBoolean();
    
                        cb_sps_servo_tuer_zu_soll.IsChecked = SPS_Servo_Tuer_geschlossen_SOLL;
                        break;
    
                    //SPS_Schuetz_Steckdose_EIN
                    case 13:
                        SPS_Schuetz_Steckdose_EIN = binReader.ReadBoolean();
    
                        cb_steckdose_ein.IsChecked = SPS_Schuetz_Steckdose_EIN;
                        break;
    
                    //SPS_Schuetz_Pruefling_EIN
                    case 14:
                        SPS_Schuetz_Pruefling_EIN = binReader.ReadBoolean();
    
                        cb_geraet_ein.IsChecked = SPS_Schuetz_Pruefling_EIN;
                        break;
    
                    //SPS_L1_V
                    case 15:
                        SPS_L1_V = binReader.ReadInt32();
    
                        //Gemessene Spannung mit Faktor 0,0001 multiplizieren und Wert mit einer Nachkommastelle anzeigen
                        //Minuswerte nicht anzeigen (Messfehler bei offenem Kontakt)
                        if (SPS_L1_V < 0)
                        {
                            tb_l1_v.Text = "0,0";
                        }
                        else
                        {
                            tb_l1_v.Text = (Convert.ToDouble(SPS_L1_V.ToString()) * 0.0001).ToString("0.0");
                        }
                        break;
    
                    //SPS_L1_A
                    case 16:
                        SPS_L1_A = binReader.ReadInt32();
    
                        //Gemessenen Strom mit Faktor 0,000001 multiplizieren und Wert mit einer Nachkommastelle anzeigen
                         //Minuswerte nicht anzeigen (Messfehler bei offenem Kontakt)
                        if (SPS_L1_A < 0)
                        {
                            tb_l1_a.Text = "0,0";
                        }
                        else
                        {
                            tb_l1_a.Text = (Convert.ToDouble(SPS_L1_A.ToString()) * 0.000001 * 30).ToString("0.0");
                        }
                        break;
    
                    //SPS_L1_W
                    case 17:
                        SPS_L1_W = binReader.ReadInt32();
    
                        //Gemessene Leistung mit Faktor 0,01 multiplizieren und Wert mit einer Nachkommastelle anzeigen
                        //Minuswerte nicht anzeigen (Messfehler bei offenem Kontakt)
                        if (SPS_L1_W < 0)
                        {
                            tb_l1_w.Text = "0,0";
                        }
                        else
                        {
                            tb_l1_w.Text = (Convert.ToDouble(SPS_L1_W.ToString()) * 0.01 * 30).ToString("0.0");
                        }
                        break;
    
                    //SPS_L2_V
                    case 18:
                        SPS_L2_V = binReader.ReadInt32();
    
                        //Gemessene Spannung mit Faktor 0,0001 multiplizieren und Wert mit einer Nachkommastelle anzeigen
                        //Minuswerte nicht anzeigen (Messfehler bei offenem Kontakt)
                        if (SPS_L2_V < 0)
                        {
                            tb_l2_v.Text = "0,0";
                        }
                        else
                        {
                            tb_l2_v.Text = (Convert.ToDouble(SPS_L2_V.ToString()) * 0.0001).ToString("0.0");
                        }
                        break;
    
                    //SPS_L2_A
                    case 19:
                        SPS_L2_A = binReader.ReadInt32();
    
                        //Gemessenen Strom mit Faktor 0,000001 multiplizieren und Wert mit einer Nachkommastelle anzeigen
                        //Minuswerte nicht anzeigen (Messfehler bei offenem Kontakt)
                        if (SPS_L2_A < 0)
                        {
                            tb_l2_a.Text = "0,0";
                        }
                        else
                        {
                            tb_l2_a.Text = (Convert.ToDouble(SPS_L2_A.ToString()) * 0.000001 * 30).ToString("0.0");
                        }
                        break;
    
                    //SPS_L2_W
                    case 20:
                        SPS_L2_W = binReader.ReadInt32();
    
                        //Gemessene Leistung mit Faktor 0,01 multiplizieren und Wert mit einer Nachkommastelle anzeigen
                        //Minuswerte nicht anzeigen (Messfehler bei offenem Kontakt)
                        if (SPS_L2_W < 0)
                        {
                            tb_l2_w.Text = "0,0";
                        }
                        else
                        {
                            tb_l2_w.Text = (Convert.ToDouble(SPS_L2_W.ToString()) * 0.01 * 30).ToString("0.0");
                        }
                        break;
    
                    //SPS_L3_V
                    case 21:
                        SPS_L3_V = binReader.ReadInt32();
    
                        //Gemessene Spannung mit Faktor 0,0001 multiplizieren und Wert mit einer Nachkommastelle anzeigen
                        //Minuswerte nicht anzeigen (Messfehler bei offenem Kontakt)
                        if (SPS_L3_V < 0)
                        {
                            tb_l3_v.Text = "0,0";
                        }
                        else
                        {
                            tb_l3_v.Text = (Convert.ToDouble(SPS_L3_V.ToString()) * 0.0001).ToString("0.0");
                        }
                        break;
    
                    //SPS_L3_A
                    case 22:
                        SPS_L3_A = binReader.ReadInt32();
    
                        //Gemessenen Strom mit Faktor 0,000001 multiplizieren und Wert mit einer Nachkommastelle anzeigen
                         //Minuswerte nicht anzeigen (Messfehler bei offenem Kontakt)
                        if (SPS_L3_A < 0)
                        {
                            tb_l3_a.Text = "0,0";
                        }
                        else
                        {
                            tb_l3_a.Text = (Convert.ToDouble(SPS_L3_A.ToString()) * 0.000001 * 30).ToString("0.0");
                        }
                        break;
    
                    //SPS_L3_W
                    case 23:
                        SPS_L3_W = binReader.ReadInt32();
    
                        //Gemessene Leistung mit Faktor 0,01 multiplizieren und Wert mit einer Nachkommastelle anzeigen
                         //Minuswerte nicht anzeigen (Messfehler bei offenem Kontakt)
                        if (SPS_L3_W < 0)
                        {
                            tb_l3_w.Text = "0,0";
                        }
                        else
                        {
                            tb_l3_w.Text = (Convert.ToDouble(SPS_L3_W.ToString()) * 0.01 * 30).ToString("0.0");
                        }
                        break;
    
                    //SPS_Handbetrieb
                    case 24:
                        SPS_Handbetrieb = binReader.ReadBoolean();
                        break;
    
                    //SPS_Automatikbetrieb
                    case 25:
                        SPS_Automatikbetrieb = binReader.ReadBoolean();
                        break;
    
                    //SPS_Merker_Fehler_SPS
                    case 26:
                        SPS_Merker_Fehler_SPS = binReader.ReadBoolean();
                        break;
                }
            }

Ähnliche Themen

  1. Zugriff auf Twincat per ADS und Visual Basic 2008
    Von Ralle im Forum CODESYS und IEC61131
    Antworten: 7
    Letzter Beitrag: 30.01.2012, 17:47
  2. TwinCat ADS
    Von Bigchaqy im Forum CODESYS und IEC61131
    Antworten: 9
    Letzter Beitrag: 08.10.2011, 23:46
  3. Antworten: 14
    Letzter Beitrag: 30.11.2010, 16:34
  4. Informationen über den ADS Router auslesen
    Von Neals im Forum CODESYS und IEC61131
    Antworten: 2
    Letzter Beitrag: 15.01.2010, 14:13
  5. Zugriff auf DB von Windows Applikation
    Von Roos im Forum Simatic
    Antworten: 7
    Letzter Beitrag: 17.06.2009, 14:38

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •