Avatar billede rmjdk Nybegynder
07. juni 2007 - 16:54 Der er 3 kommentarer

Threadsafe kode

Jeg bruger en stump kode for at kunne opdatere GUI fra en anden tråd, men jeg forstår ikke koden 100% derfor håber jeg i kunne opklare det :)

Koden ser således ud:

            if (this.InvokeRequired)
            {
                OutputMessageDelegate del = new OutputMessageDelegate(OutputMessage);
                IAsyncResult ar = this.BeginInvoke(del, new object[] { msg });
                this.EndInvoke(ar);
                return;
            }

Hvorfor bliver resultatet af EndInvoke ikke brugt?
Avatar billede rmjdk Nybegynder
07. juni 2007 - 17:21 #1
Okay, resultatet af EndInvoke bliver ikke brugt da metoden dette sker i ikke resulterer noget, EndInvoke skal kaldes da BeginInvoke ellers vil fortsætte.

Jeg forstår ikke hvordan det er muligt at køre BeginInvoke samt andet kode fra en anden tråd, da jeg ikke kan opdatere GUI, hvor er forskellen?
Avatar billede leharpf Nybegynder
07. juni 2007 - 23:07 #2
Hej

For at man kan opdatere GUI skal man stå på hoved tråden, der hvor formen har sin message loop.
For at skifte til denne tråd bruger man Invoke, med dette kald skifter man til hovedtråden og man kan opdatere sin GUI.

Invoke er en samling af BeginInvoke og EndInvoke, dvs. Invoke kalder i princippet BeginInvoke og bagefter EndInvoke.

Følgende kode bruger Invoke:
private delegate void DelegateUpdateUI(string text);
private void UpdateUI(string text)
{
if(lblResult.InvokeRequired)
{
  lblResult.Invoke(new DelegateUpdateUI(UpdateUI),new object[] { text }));
}
else
{
lblResult.Text = text;
}
}

Det er sker er når du vil opdater en label på din form fra en anden tråd kalder du UpdateUI("Test"), metoden bliver kaldt, og når til InvokeRequired, hvilket finder ud af om du er på hoved tråden, hvis ikke udføres der en Invoke (Du bliver skiftet om til hovedetråden), og nu kaldes din delegateMethod, som er den samme method UpdateUI, så nu kommer vi ind i UpdateUI igen, men denne gang er vi på Hovedtråden og når vi kommer ned til InvokeRequired, vil vi ende i else methoden, og så får vi sat vores label til det vi ønsker.

BeginInvoke og EndInvoke er bare en måde at gøre det asynkront, det er ofte ikke nødvendigt, medmindre man skal gøre noget på sin form der tager langtid.

Mvh.
Per
Avatar billede brian0905 Nybegynder
08. juni 2007 - 14:21 #3
Det tip jeg skriver nu kan ikke anbefales, det er bedre at bruge invoke, men jeg bruger selv dette i mindre og simple guis: http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.checkforillegalcrossthreadcalls.aspx

Sæt den property til false på formen, så checker den ikke efter om kaldet kommer fra en anden tråd... igen hvis du laver bare en tilnærmelsesvis avanceret ui kan det ikke anbefales... det kan give flere problemer end det løser...
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