Jump to content

C# Programm hängt beim Beenden


Recommended Posts

Hallo,

ich habe gestern mein Starterkit bekommen und bin schon ziemlich begeistert wie einfach das Teil zu programmieren ist und wie zuverlässig es läuft. Ein Problem habe ich noch. Wenn ich mein Form schließe hängt das Programm fest. Ich muss es über das Visual Studio beenden. Hat jemand eine Idee? Hier ist der Code:

 

public partial class Form1 : Form
    {
        Timer timer;
        Timer soundTimer;
        IPConnection ipconn;
        BrickletLCD20x4 lcd;
        BrickletRotaryPoti poti;
        BrickletDistanceIR ir;
        BrickletAmbientLight al;
        int distance;

        // Callback function for position callback (parameter has range -150 to 150) 
        void PositionCB(short position)
        {
            lcd.WriteLine(1, 0, "    ");
            lcd.WriteLine(1, 0, Convert.ToString(position));
        }
        void DistanceCB(ushort distance)
        {
            this.distance = distance / 10;
            lcd.WriteLine(2, 0, "     ");
            lcd.WriteLine(2, 0, Convert.ToString(this.distance) + "cm");
        }
        void IlluminanceCB(ushort illuminance)
        {
            lcd.WriteLine(3, 0, "          ");
            lcd.WriteLine(3, 0, Convert.ToString(illuminance / 10) + " lux");
        }
        public Form1()
        {
            InitializeComponent();
            timer = new Timer(); // Timer anlegen
            timer.Interval = 1000; // Intervall festlegen, hier 100 ms
            soundTimer = new Timer();
            soundTimer.Interval = 200;
            soundTimer.Tick += new EventHandler(soundTimer_Tick);
            soundTimer.Start();
            timer.Tick+=new EventHandler(t1_Tick); // Eventhandler ezeugen der beim Timerablauf aufgerufen wird
            try
            {
                ipconn = new IPConnection("localhost", 4223);
                lcd = new BrickletLCD20x4("8vY"); // Create device object
                poti = new BrickletRotaryPoti("8bh"); // Create device object
                ir = new BrickletDistanceIR("8qC");
                al = new BrickletAmbientLight("863");
                ipconn.AddDevice(lcd); // Add device to IP connection
                ipconn.AddDevice(poti); // Add device to IP connection
                ipconn.AddDevice(ir);
                ipconn.AddDevice(al);
                lcd.BacklightOn();
                lcd.ClearDisplay();
                poti.SetPositionCallbackPeriod(100);
                poti.RegisterCallback(new BrickletRotaryPoti.Position(PositionCB));
                ir.SetDistanceCallbackPeriod(100);
                ir.RegisterCallback(new BrickletDistanceIR.Distance(DistanceCB));
                al.SetIlluminanceCallbackPeriod(500);
                al.RegisterCallback(new BrickletAmbientLight.Illuminance(IlluminanceCB));
                this.timer.Start();
                timer.Start(); // Timer starten
            }
            catch (Exception f)
            {
                MessageBox.Show(f.ToString());
            }
        }

        void soundTimer_Tick(object sender, EventArgs e)
        {
            if (chk_sound.Checked)
            {
                Beep.BeepBeep(100, 1000, distance*4);
            }
        }

        void t1_Tick(object sender, EventArgs e)
        {
            lcd.WriteLine(0, 0, DateTime.Now.ToString());
        }

        void Form1_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
        {
            if (timer != null)
            {
                timer.Stop();
            }
            if (soundTimer != null)
            {
                soundTimer.Stop();
            }
            if (lcd != null)
            {
                lcd.BacklightOff();
                lcd.ClearDisplay();
            }
            if (ipconn != null)
            {
                ipconn.JoinThread();
            }
        }
    }

Link to comment
Share on other sites

Mach mal statt JoinThread ein Destroy auf der IPConnection, dann müssten die beiden Threads von ihr sterben gehen, die sind nämlich keine Background Threads und verhindern somit, dass das Programm sich beenden kann.

 

Destroy würgt die IPConnection einfach ganz unsanft ab und dann sollte Ruhe im Karton sein :D

Link to comment
Share on other sites

Dito. Allerdings wüsste ich anhand der Bindings nicht wie es "sanfter" gehen sollte. Ich hab nicht in den Source geschaut wie "unsanft" wird denn da gearbeitet? *Set all the things null!* Style? Selbst wenn solange Fehler abgefangen werden ist dies besser als auf einen Thread Warten der vermutlich nie beendet wird.

 

@TF: Ein "ipcon.Close()" für einen sauberen Ausstieg wäre gut.

Link to comment
Share on other sites

Das selbe Problem hatte ich auch und konnte es nur über das abwürgen mit Destroy machen.

 

Wobei abwürgen das falsche Wort ist. Innerhalb der Destroy() Methode wird versucht den Socket zu closen und die Callback Queue zu schließen.

Destroy() ist daher vllt etwas unpassend und sollte eventuell einfach in Close() geändert werden.

 

Schöne Grüße

Link to comment
Share on other sites

Naja, die aktuelle Implementierung schließt halt den Socket, was im Receive-Thread zu ner IOException führt ^^

 

Deswegen meinte ich unsanft, grundsätzlich erfüllt es aber den Zweck eines Close. Close kommt auch der Standard-namensgebung in .NET am nächsten ^^

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...