Gå til innhold

C#: Hvordan oppdatere GUI fra "worker thread"?


Anbefalte innlegg

Jeg har en metode, "ReadData", som kjører på en annen tråd. Denne metoden skal ta imot data over serieporten og oppdatere diverse controller på UI.

 

Testkoden jeg har laget fungerer, men jeg tror ikke den er helt etter boka, på hvordan dette skal gjøres.

Har googlet etter svar, og funnet en del om emnet men greier ikke helt å forstå det jeg leser. Har veldig liten erfaring med "Delegates" og "Invoke" som jeg ser går igjen på dette temaet. Så om noen har lyst å hjelpe meg litt på vei hadde jeg blitt glad.

 

 

Her er testkoden, har simulert metoden som leser data fra serieporten, den oppdaterer bare en status strip, sover i 3 sek og gjentar seg selv.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ArduQuadConf
{

   public partial class MainForm : Form
   {

       static bool _continue;
       Thread readThread;


       public MainForm()
       {
           InitializeComponent();

           _continue = true;
           readThread = new Thread(new ThreadStart(ReadData));
       }


       private void buttonConnect_Click(object sender, EventArgs e)
       {
           readThread.Start();
       }


       public void UpdateUI(string str)
       {
           toolStripStatusLabel.Text = str;
       }


       public void ReadData()
       {
           int i = 0;
           while(_continue)
           {
               UpdateUI(i.ToString());
               Thread.Sleep(3000);
               i++;
           }
       }


       private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
       {
           _continue = false;

           if (readThread.IsAlive)
           { 
               readThread.Join();
           }
       }


   }
}

Lenke til kommentar
Videoannonse
Annonse

Problemet er at du ikke kan endre GUI fra en annen tråd. For å omgå denne begrensningen, lager du en metode som skal kjøres under den andre tråden.

 

For å gjøre det helt enkelt, kan du gjøre slik:

 

public void UpdateUi(string str)
{
 Invoke( () => 
   {
      toolStripStatusLabel.Text = str;
   });
}

 

Dette lager en anonym funksjon som blir utført på GUI tråden.

Lenke til kommentar

Takker for raskt svar, har lest litt mer om dette nå og kommet fram til koden under.

Er dette en ok måte å gjøre det på?

 

namespace ArduQuadConf
{

   public partial class MainForm : Form
   {
       delegate void UpdateUIDelegate(string value);

       static bool _continue;
       Thread readThread;


       public MainForm()
       {
           InitializeComponent();

           _continue = true;
           readThread = new Thread(new ThreadStart(ReadData));
           readThread.IsBackground = true;
       }


       private void buttonConnect_Click(object sender, EventArgs e)
       {
           readThread.Start();
       }


       public void UpdateUI(string str)
       {

           if (InvokeRequired)
           {
               BeginInvoke(new UpdateUIDelegate(UpdateUI), new object[] { str });
           }
           else
           {
               toolStripStatusLabel.Text = str;
           }
       }


       public void ReadData()
       {
           int i = 0;
           while(_continue)
           {
               UpdateUI("Serial listener tråd: " + i.ToString());
               Thread.Sleep(3000);
               i++;
           }
       }


       private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
       {
           _continue = false;

           if (readThread.IsAlive)
           { 
               readThread.Join();
           }
       }

       private void button1_Click(object sender, EventArgs e)
       {
           UpdateUI("UI tråd");
       }


   }
}

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...