Announcement

Collapse
No announcement yet.

Invoke fürt zum freeze bei Seriellem GPS input

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Invoke fürt zum freeze bei Seriellem GPS input

    Hallo Forumgemeinschaft,

    ich arbeite momentan an einer GPS Anwendung für Windows Mobile 6 Handys und bin dabei auf ein kleines Problem gestoßen.

    Ich rufe die Daten meines GPS Senders ganz normal, wie auch im MSDN beschrieben, über den COM-Port ab und kann diese in die Console ausgeben. Wenn ich nun allerdings die Daten in ein Textfeld in meiner Anwednung ausgeben möchte oder den String bearbeite um damit arbeiten zu können, bekomme ich einen Fehler.

    Das Problem habe ich mittels des Forums schon erkannt und auf die unterschiedlichen Threads zurückgeführt. Ich hatte mir mehrere Sachen angeschaut und würde vermuten das mein Ansatz eigentlich gehen müsste, dem ist aber scheinbar nicht so. Das Problem ist auch, dass es soviele verschiedene Lösungen gibt mit Invoke zu arbeiten und ich eventuell durch die nutzung vom CompactFramework 3.5 gewisse Einschränkungen habe.

    Hier mal der Code:
    Code:
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.IO.Ports;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace SmartDeviceProject3
    {
        public partial class gps2bla : Form
        {
            static SerialPort _serialPort;
            static bool _continue = true;
    
            public gps2bla()
            {
                InitializeComponent();
            }
            private void button1_Click_1(object sender, EventArgs e)
            {
                InitializeComport();
            }
            public void InitializeComport() // Quelle: MSDN
            {
                string name;
                string message;
                StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
                Thread readThread = new Thread(Read);
    
                // Create a new SerialPort object with default settings.
                _serialPort = new SerialPort();
    
                // Allow the user to set the appropriate properties.
                _serialPort.PortName = "COM1";
                _serialPort.BaudRate = 38400;
                _serialPort.Parity = Parity.None;
                _serialPort.DataBits = 8;
                _serialPort.StopBits = StopBits.One;
                _serialPort.Handshake = Handshake.None;
    
                // Set the read/write timeouts
                _serialPort.ReadTimeout = 500;
                _serialPort.WriteTimeout = 500;
    
                _serialPort.Open();
                _continue = true;
                readThread.Start();
    
                Console.Write("Name: ");
                name = Console.ReadLine();
    
                Console.WriteLine("Type QUIT to exit");
    
                while (_continue)
                {
                    message = Console.ReadLine();
    
                    if (stringComparer.Equals("quit", message))
                    {
                        _continue = false;
                    }
                    else
                    {
                        _serialPort.WriteLine(
                            String.Format("<{0}>: {1}", name, message));
                    }
                }
                readThread.Join();
                _serialPort.Close();
            }
    
            public void Read() // Bis auf boxchange aufruf wie MSDN Beispiel
            {
                while (_continue)
                {
                    try
                    {
                        string message = _serialPort.ReadLine();
                        //Console.WriteLine(message);
                        boxchange(message);
                    }
                    catch (TimeoutException ex)
                    {
                        //Console.WriteLine("TimeoutException", ex.Message);
                    }
                }
            }
            public void boxchange(object message) // Beispielmethode, hier sollen später die GPS Daten in Geschwindigkeit, Strecke usw. umgerechnet werden
            {
                Console.WriteLine(message);
                if (this.InvokeRequired)
                {
                    this.textBox1.BeginInvoke(new WaitCallback(boxchange), message);
                    return;
                }
                else
                {
                    this.textBox1.Text = (string)message;
                }
            }
    Ich wäre euch dankbar wenn mir jemand sagen könnte was ich falsch mache.
    Ich bin nicht an das Abfragen der Ports gebunden, falls also jemand ein anderes Beispiel liefert, bin ich dafür offen. Wichtig ist mir nur, dass ich aus den abgefragten GPS Daten später Geschwindigkeit, zurückgelegte Entfernung, Zeit und natürlich die Position selbst berechnen kann.

    Über das "wie", habe ich mir noch nicht so die gedanken gemacht aber eins nach dem anderen

  • #2
    Nimm

    Code:
     
                while (_continue)
                {
                    message = Console.ReadLine();
    
                    if (stringComparer.Equals("quit", message))
                    {
                        _continue = false;
                    }
                    else
                    {
                        _serialPort.WriteLine(
                            String.Format("<{0}>: {1}", name, message));
                    }
                }
                readThread.Join();
               _serialPort.Close();
    raus. Damit hast du eine Art busyWaiting in deinem GUI Thread implementiert. Heißt in deinem GUI Thread werden keine Messages mehr abgearbeitet bis der andere Thread mit dem lesen beendet ist. Macht übrigens Threading ziemlich überflüssig wenn man einen Thread mehr oder weniger solange anhält bis der andere fertig ist.

    Wenn du dann sogar aus dem Read Thread im GUI Thread noch was ausführen willst hängst du dir die Anwendung auf, den GUI Thread hast du ja praktisch angehalten(rotiert nur noch in deiner While Schleife).


    Ich würde vorschlagen die while Schleife sterben zu lassen und dafür

    Code:
                _continue = false;
                readThread.Join();
               _serialPort.Close();
    zum beenden hinter einen weiteren Button zu plazieren (oder im Form_Closing Event).
    Zuletzt editiert von Ralf Jansen; 05.01.2009, 15:34.

    Comment


    • #3
      hmm, selbe Problem ;/

      Comment


      • #4
        Also das Problem ist, dass die Art wie ich den Com-Port abfrage alles Blockiert und der Fehler jetzt wohl doch nicht am Invoke liegen musst.

        Mit deiner änderung Ralf, allerdings nur wenn _continue = true ist, läuft es Prog zwar aber Blockiert ebenfalls.

        _continue = false liefert eine Zeile in die Console und hört dann auf, allerdings keine Blockierung.

        *grübel*



        problem gelöst, bitte close


        ----------------------------
        Zuletzt editiert von sKaH; 06.01.2009, 05:08.

        Comment


        • #5
          lösung bitte Posten
          Unsere Jugend ist unerträglich, unverantwortlich und entsetzlich anzusehen! - Aristoteles

          Comment


          • #6
            public void InitializeComport()
            {
            StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
            Thread readThread = new Thread(Read);

            _serialPort = new SerialPort();

            _serialPort.PortName = "COM1";
            _serialPort.BaudRate = 38400;
            _serialPort.Parity = Parity.None;
            _serialPort.DataBits = 8;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Handshake = Handshake.None;

            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 500;

            _serialPort.Open();
            _continue = true;
            readThread.Start();
            }

            Comment

            Working...
            X