Avatar billede Spotgun Seniormester
07. marts 2006 - 12:42 Der er 8 kommentarer og
1 løsning

Opdater GUI fra flere forskellige tråde?

Jeg sidder og roder med et program (WinForm), som opretter to tråde, som hver skal melde tilbage til GUI'en, og opdatere hver sin RichTextBox.

I starten kørte jeg kun med en enkelt tråd, og havde lavet en thread-safe metode til at opdatere boksen på (vha. delegate/invoke). Det fungerede rigtigt fint - lige indtil jeg tilføjede tråd nr. to, som skulle opdatere en anden box.

Jeg lavede igen en selvstændig metode med en delegate til, som skulle bruges til det tilfælde, men det fungerer ikke. Programmet crasher og melder at tråden er opdateret "unsafe".

Så jeg tænkte på om jeg mangler noget lock/synchronize, siden der nu er to tråde der egentligt kæmper om at få lov til at bruge en metode på hoved/gui-tråden... Har rodet lidt med det, men er ikke kommet frem til noget brugbart.
Avatar billede jakob1979 Nybegynder
07. marts 2006 - 13:35 #1
Der findes et keyword i C# som hedder unsafe... måske kan du løse det ved at angive din "opdateringsmetode" som unsafe, og kompilere med /unsafe
Avatar billede Spotgun Seniormester
07. marts 2006 - 14:11 #2
Jeg vil helst ikke rode mig ud i at lave nogle unsafe kald i mit program, og desuden må det vel være muligt på en threadsafe måde at tilgå GUI'en fra flere forskellige tråde...
Avatar billede casualty Nybegynder
07. marts 2006 - 18:03 #3
Det kan måske hjælpe at bruge invoke:


String textToAppend="";

private void UpdateTextbox(String text){
    this.textToAppend = text;
    this.Invoke(new EventHandler(SetText),null);
}

public void SetText(object sender, EventArgs e){
    DateTime now = DateTime.Now;
    this.richTextBox.AppendText(textToAppend);
}
Avatar billede casualty Nybegynder
07. marts 2006 - 18:03 #4
Den plejer at klare det for mig...
Avatar billede casualty Nybegynder
07. marts 2006 - 18:14 #5
Og bare glem "DateTime now"
Avatar billede Spotgun Seniormester
09. marts 2006 - 16:39 #6
Jeg bruger allerede invokes/delgates på mine gui-update funktioner - som sagt, uden det store held.

Det ser desuden ud til at det kun er den sidst-startede tråd der kan opdatere gui'en. Er der nogen sammenhæng dér evt?
Avatar billede mikkelbm Nybegynder
11. marts 2006 - 14:26 #7
Hvis man bruger .NET 2.0 kan man lave anonyme metoder, så man er fri for globale variabler der bare er til besvær:

private void UpdateTextbox(String text)
{
    this.Invoke(new MethodInvoker(delegate()
    {
        this.richTextBox.AppendText(text);
    });
}
Avatar billede Spotgun Seniormester
13. marts 2006 - 15:07 #8
Jeg forstår ikke helt hvorfor, men det ser ud til at mikkelbm's forslag virker... Er der forskel på at invoke på den måde, i forhold til at sådan her:

        public delegate void LogClientEventHandler(string text);

        public void LogClient(string text)
        {
            if (rtbClient.InvokeRequired)
            {
                rtbClient.Invoke(new LogClientEventHandler(LogClient), new object[] { text });
            }
            else
            {
                rtbClient.AppendText(text + "\r");
            }
        }

Hvis jeg bruger den delegate-version, så er det kun den sidst-oprettede tråd der kan opdatere gui'en. 

Anyways - Mikkelbm, kommer du med et svar?
Avatar billede mikkelbm Nybegynder
13. marts 2006 - 15:11 #9
Kommer her...
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