Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   C# .Net-eigene ComPort-Klasse extrem langsam?! (https://www.delphipraxis.net/127715-net-eigene-comport-klasse-extrem-langsam.html)

Meflin 17. Jan 2009 21:01


.Net-eigene ComPort-Klasse extrem langsam?!
 
Moin moin!

Ich spiele grade ein bisschen mit Visual C# rum. Ich hab einen GPS-Empfänger über PCMCIA angeschlossen, der Daten über einen Comport sendet. Zu diesem Empfänger gabs auch ein Testprogramm. Wenn ich mit diesem Testprogramm teste, bekomme ich mindestens einen Datensatz pro Sekunde rein.

Nuja. Hab mir also ein C#-Programm geschrieben, was einfach nur mittels System.IO.Ports.SerialPort und den entsprechenden Geräteeinstellungen eben diese Datensätze empfängt - aber WESENTLICH langsamer. Manchmal kommt minutenlang garnichts, und das kann eigentlich nicht stimmen.

Also hab ich auch mal andere allgemeine Comport-Programme getestet, auch die empfangen schneller.

Ich bin da gerade etwas ratlos :gruebel:

Irgendjemand ne Idee, woher diese Diskrepanz kommen könnte?


Hier der Code, falls sich jemand durchquälen möchte :stupid:
Code:
namespace GPStat
{
    public partial class Form1 : Form
    {
        SerialPort port = new SerialPort();

        public Form1()
        {
            InitializeComponent();
        }

        private delegate void MethInvDel(string text);

        private void SetText(string text)
        {
            if (tbxRawData.InvokeRequired)
            {
                tbxRawData.BeginInvoke(new MethInvDel(SetText), text);
            }
            else
            {
                tbxRawData.Text += "\r\n" + text;
                tbxRawData.Select(tbxRawData.Text.Length + 1, 2);
                tbxRawData.ScrollToCaret();
            }
        }


        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string NewPackage = port.ReadLine();
            SetText(NewPackage);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] ports = SerialPort.GetPortNames();
            for (int i = 0; i < ports.Length; i++)
            {
                cbxPortName.Items.Add(ports[i]);
            }
            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {

            switch (btnConnect.Text)
            {
                case "Connect":
                    tbxRawData.Clear();
                    port.PortName = cbxPortName.Text;
                    port.BaudRate = Convert.ToInt32(cbxBaudRate.Text);
                    port.DataBits = Convert.ToInt32(cbxDataBits.Text);

                    // Set Parity
                    switch (cbxParity.Text)
                    {
                        case "none":
                            port.Parity = Parity.None;
                            break;
                        case "odd":
                            port.Parity = Parity.Odd;
                            break;
                        case "even":
                            port.Parity = Parity.Even;
                            break;
                        case "mark":
                            port.Parity = Parity.Mark;
                            break;
                        case "space":
                            port.Parity = Parity.Space;
                            break;
                    }

                    // Set Stop Bits
                    switch (cbxStopBits.Text)
                    {
                        case "none":
                            port.StopBits = StopBits.None;
                            break;
                        case "1":
                            port.StopBits = StopBits.One;
                            break;
                        case "1.5":
                            port.StopBits = StopBits.OnePointFive;
                            break;
                        case "2":
                            port.StopBits = StopBits.Two;
                            break;
                    }

                    btnConnect.Text = "Disconnect";
                    port.Open();
                    break;

                case "Disconnect":
                    btnConnect.Text = "Connect";
                    port.Close();
                    break;
            }

        }


    }
}

Meflin 18. Jan 2009 12:12

Re: .Net-eigene ComPort-Klasse extrem langsam?!
 
Weitere ausführliche Tests haben ergeben, dass das ganze äußerst instabil läuft :cry:

Führe ich das ganze außerhalb der IDE aus, schmiert mir das ganze beim Click auf Connect meist mit folgender Fehlermeldung ab:
Code:
Der E/A-Vorgang wurde wegen eines Threadendes oder einer Anwendungsanforderung abgebrochen.
(ist dann zwar nicht sichtbar, aber auch mit Debugger reproduzierbar).

Selbiger Fehler tritt sporadisch auch beim Schließen des Ports auf.


Irgendwie also alles in allem nicht so das wahre. Ich kann aber prinzipiell auch keinen Logikfehler in meinem Code entdecken :(

Wie macht man es denn nur richtig :?:

thkerkmann 18. Jan 2009 12:35

Re: .Net-eigene ComPort-Klasse extrem langsam?!
 
Hi,

hast Du schonmal hier CodeProjectgesucht.

gibt jede Menge dazu und eingegrenzt auf c# sind es immer noch 5 Seiten.

Viel Erfolg.

Meflin 18. Jan 2009 14:21

Re: .Net-eigene ComPort-Klasse extrem langsam?!
 
Hm, hab mir grade mal das hier angesehen, weil es meinem Vorhaben ziemlich nahe kommt:
http://www.codeproject.com/KB/cs/GpsMapping.aspx

Der Code ist ja noch viel grottiger als meiner. Da wird ein Timer verwendet um zu pollen, anstatt ein Callback zu registrieren :mrgreen:

Und abgesehen davon: Das Ding schmiert genauso ab wie meins. Das selbe Verhalten, die selben Fehler :?

kiar 18. Jan 2009 19:39

Re: .Net-eigene ComPort-Klasse extrem langsam?!
 
Moin,

du übergibst den kömpletten Thread an den GUI- Thread, Hier liegt dein Fehler
Code:

private void DoSetText(string text)
        {
            //

                tbxRawData.Invoke(new MethInvDel(SetText), text);
            //
        } 

private void SetText(){....}
probiere es mal so.

Raik

Meflin 18. Jan 2009 20:23

Re: .Net-eigene ComPort-Klasse extrem langsam?!
 
Wenn ich dich richtig verstanden habe so (was ich aber nicht ganz verstehe :stupid:)?
Code:
private delegate void MethInvDel(string text);

        private void DoSetText(string text)
        {
            tbxRawData.Invoke(new MethInvDel(SetText), text);
        }

        private void SetText(string text)
        {
            tbxRawData.Text += "\r\n" + text;
            tbxRawData.Select(tbxRawData.Text.Length + 1, 2);
            tbxRawData.ScrollToCaret();
        }


        private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string NewPackage = port.ReadLine();
            DoSetText(NewPackage);
        }
Das tuts auch nicht - stürzt nach wie vor aus ungeklärter Ursache ab, und geschwindigkeitsmäßig ist alles beim Alten :(

kiar 18. Jan 2009 20:36

Re: .Net-eigene ComPort-Klasse extrem langsam?!
 
Moin,

sorry der fehler lag bei mir nimm den
Code:

private void DoSetText(string text)
        { If (this.InvokeRequired){
            this.Invoke(new MethodInvoker(SetText));
            return;
        }}
raik


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz