Avatar billede sigurdsuhm Nybegynder
12. august 2008 - 23:23 Der er 11 kommentarer og
1 løsning

Thread Safe Code og Invoke

Jeg arbejder i øjeblikket med et simpelt chat program for at blive bedre til at bruge TcpClients og så videre. Jeg har dog et problem.
Jeg vil gerne ændre en TextBoxs Text property fra en anden Thread end den den er skabt i, og dette har jeg løst ved brug af InvokeRequired og Invoke.
Men problemet er, at jeg gerne vil have linjeskift mellem de beskeder, der modtages, og det kan jeg ikke rigtig løse. Når jeg invoker bliver den nye tekst bare skrevet over den gamle. Her er den funktion jeg bruger nu:

private delegate void WriteMsgDel(string msg);

        public void WriteMessage(string msg)
        {
            if (this.txtMsgArea.InvokeRequired)
            {
                WriteMsgDel d = new WriteMsgDel(WriteMessage);
                this.txtMsgArea.Invoke(d, msg);
            }
            else
                this.txtMsgArea.Text = String.Format("{0:t}", DateTime.Now) + "  -  " + msg + Environment.NewLine + Environment.NewLine + this.txtMsgArea.Text;
        }
Avatar billede arne_v Ekspert
13. august 2008 - 04:05 #1
Følgende virker for mig:

        void AppendTextBox1(string msg)
        {
            textBox1.Text += (msg + "\r\n");
        }
        void Run()
        {
            for(int i = 0; i < 10; i++)
            {
                string msg = "Dette er linie #" + i;
                if(textBox1.InvokeRequired)
                {
                    textBox1.Invoke((MethodInvoker)delegate() { AppendTextBox1(msg); });
                }
                else
                {
                    AppendTextBox1(msg);
                }
                Thread.Sleep(2000);
            }
        }
        void Button1Click(object sender, EventArgs e)
        {
            (new Thread(Run)).Start();
        }
Avatar billede sigurdsuhm Nybegynder
13. august 2008 - 12:56 #2
Jo det løste lidt. Men det ser ud som om at min client bliver ved med at sende den samme streng og så bare overskriver de første tegn med det nye man prøver at sende.
Så f.eks.:
Client:    Sigurd Suhm has connected
Server:    Sigurd Suhm has connected.
Client.    Hej
Servern:  Hejurd Suhm has connected.

Og linjeskiftne stopper med at fungere efter det første... Nogle idéer til hvad jeg kan have overset?
Avatar billede arne_v Ekspert
13. august 2008 - 19:33 #3
maa vi se koden som den ser ud nu ?
Avatar billede sigurdsuhm Nybegynder
13. august 2008 - 19:49 #4
Skal prøve at gøre det så overskueligt som muligt.

Disse to funktioner findes i en klasse kaldet Server:

private void HandleClientComm()        // Denne funktion kører som en tråd
        {
            NetworkStream clientStream = client.GetStream();

            byte[] message = new byte[4096];
            int bytesRead;

            while (!terminate)
            {
                bytesRead = 0;

                try
                {
                    bytesRead = clientStream.Read(message, 0, 4096);
                }
                catch
                {
                    break;
                }

                if (bytesRead == 0)
                    break;

                ASCIIEncoding encoder = new ASCIIEncoding();
                ProcessInput(encoder.GetString(message));
            }
        }

        private void ProcessInput(string input)
        {
            switch (input.Substring(0, 4))
            {
                case ".01.":
                    clientList.Add(new Client(input.Substring(4, input.Length - 4), client));
                    Program.mainForm.WriteMessage(input.Substring(4, input.Length - 4) + " added to active clients.");
                    break;
                default:
                    Program.mainForm.WriteMessage(input);
                    break;
            }
        }

De næste to ligger i koden til den primære form:

        public void WriteMessage(string msg)
        {
            if (this.txtMsgArea.InvokeRequired)
            {
                this.txtMsgArea.Invoke((MethodInvoker)delegate() { AppendMsgArea(msg); });
            }
            else
                AppendMsgArea(msg);
        }

        public void AppendMsgArea(string msg)
        {
            this.txtMsgArea.Text += String.Format("{0:t}", DateTime.Now) + "  -  " + msg + "\r\n\r\n";
        }

Sig til hvis i har brug for mere.
Avatar billede arne_v Ekspert
13. august 2008 - 20:11 #5
Den er gal med din Read.

ProcessInput(encoder.GetString(message, 0, bytesRead));

boer hjaelpe.
Avatar billede arne_v Ekspert
13. august 2008 - 20:12 #6
Men meget nemmere og bedre: wrap din NetworkStream i en StreamReader og laes linier !!
Avatar billede sigurdsuhm Nybegynder
13. august 2008 - 20:19 #7
Den første løsning ændrer ikke rigtig noget. Kunne jeg lokke dig til at give et eksempel på hvordan min NetworkStream behandles i en StreamReader? Har leget lidt rundt med det uden noget resultat.
Avatar billede arne_v Ekspert
13. august 2008 - 20:24 #8
Det burde fjerne "Hejurd" problemet.
Avatar billede arne_v Ekspert
13. august 2008 - 20:26 #9
private void HandleClientComm()        // Denne funktion kører som en tråd
        {
            StreamReader clientStream = new StreamReader(client.GetStream());
            string line;
            while((line = clientStream.ReadLine()) != null)
            {
                ProcessInput(line);
            }
        }
Avatar billede sigurdsuhm Nybegynder
14. august 2008 - 13:58 #10
Jeg takker mange gange for hjælpen. Det virker en del bedre nu. Har stadig meget at lære, men det her hjalp mig med at få lidt af det lidt mere ind under huden.
Avatar billede sigurdsuhm Nybegynder
14. august 2008 - 14:03 #11
Øh... hvordan er det lige jeg uddeler de lovede point? Har ledt forgæves efter funktionen...
Avatar billede arne_v Ekspert
14. august 2008 - 14:59 #12
jeg skal foerste smide et svar som nu
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester