Avatar billede mjall0w Nybegynder
29. august 2010 - 23:11 Der er 11 kommentarer og
1 løsning

Kalde background thread og lave cross-threading

Hej.
Kalder diverse funktioner i en background-thread, og får en fejl om "Fejl på tvær af tråde".
Jeg har prøvet at en cross-thread præcis som de gør, men giver mig stadig fejl om "Handling på tværs af tråde......".

I mange af de funktioner jeg kalder benytter jeg rigtig mange tekstbokse og labels der konstant skal ændres værdi af.

Hvordan kan jeg løse mit problem?

Håber der er hjælp at finde derude.

PS. føler ikke der er så meget grund til at paste min code, da det er en helt almindelig background worker der kalder en funktion, hvori der ændres en textbox's indhold.
Avatar billede Syska Mester
29. august 2010 - 23:22 #1
"Jeg har prøvet at en cross-thread præcis som de gør, men giver mig stadig fejl om "Handling på tværs af tråde......"."

Say what har du prøvet ?
Avatar billede Syska Mester
29. august 2010 - 23:24 #2
Kig her:
http://www.eksperten.dk/spm/917330

Det burde give en ide om hvordan det skal løses.

mvh
Avatar billede lasserasch Juniormester
30. august 2010 - 00:56 #3
Eller du kan kigge på det her eksempel. En anden vej at gå...

http://www.r-coding.dk/downloads/eksperten/backgroundworkereksempel2.zip

mvh.
Lasse
Avatar billede mjall0w Nybegynder
30. august 2010 - 08:55 #4
Hov, var lidt for hurtigt der.
Når fejlen opstår i MS VS, kommer de med link til nogle eksempler hvor de gør det, og hvis jeg gør det præcis som de gør det der, får jeg stadig fejl,
http://msdn.microsoft.com/en-us/library/ms171728(VS.90).aspx

Men der findes simpelthen ingen anden måde end at tjekke om det skal Invokes hver gang jeg skal ændre et objekt? Det drejer sig nemlig og rigtig MANGE objekter jeg løbende skal ændre.

Det backgroundworker eksempel virker desværre heller ikke, da det er en masse funktioner jeg kalder så snart jeg aktiverer min background.
Avatar billede Syska Mester
30. august 2010 - 09:38 #5
WPF har vist noget der er bedre ... men siden du bruger WinForms, bliver du nok nødt til at tage den her vej, jeg har endnu ikke set andre måder det kan løses på.

Men det kan helt sikkert laves meget generisk, så der ikke er så meget kode der skal laves alligevel.
Avatar billede mjall0w Nybegynder
30. august 2010 - 10:28 #6
Ja, det er sku noget værre pis det her ;)
Well, fandt frem til jeg vil benytte det her,

                    this.login.Invoke((ThreadStart)delegate()
                    {
                        login.Enabled = true;
                    });

og det virker helt efter planen.
Så for at gøre det nemmere må jeg jo skrive en funktion der tillægger sig de Form objekter jeg vil redigere, så jeg er fri for at skrive den kode hver gang jeg skal ændre noget i min form, men bare kan kalde funktionen hvori jeg angiver hvilket objekt jeg vil ændre ved.

Tak for hjælpen.

Smider du et svar buzzzzzz?
Avatar billede Syska Mester
30. august 2010 - 10:51 #7
Ja, men i sidste ende er det for din egen skyld det blev lavet sådan her i .NET 2 og frem ...

Nogen gange ville det være nemmere at man kunne, det vil jeg give dig ret i, det burde være en setting.

svar.
Avatar billede lasserasch Juniormester
30. august 2010 - 12:23 #8
Men hvorfor bruger du så ikke en background worker. Det er jo lige netop det som den kan. Altså opdatere din form fra en anden tråd.

Umiddelbart virker det da lidt skørt at skrive sin egen funktion til det, når den findes i forvejen???

Mvh.
Lasse
Avatar billede mjall0w Nybegynder
31. august 2010 - 21:26 #9
lasserasch, det er fordi jeg har skrevet et forholdsvis stort program nu, og det er delt op i funktioner. Programmet kører sig selv hele tiden i løkker og foretager det ene på det andet gang på gang. Og når jeg starter "startfunktionen()" fra backgroundworker, får jeg disse fejl med at jeg har kaldt dem fra en anden tråd.
Det er derfor jeg gør det, ellers kan jeg kun give dig helt ret.
Avatar billede aaberg Nybegynder
01. september 2010 - 14:02 #10
Hvis du ikke gider lave invokes for samtlige operationer, så kan du altid sætte følgende property:
Form.CheckForIllegalCrossThreadCalls = false;

Så vil dine cross-thread operationer virke helt fint.

Bare husk på at der er en grund til at cross-thread operationer som default ikke er lovlige. Hvis du ikke holder tungen lige i munden, risikere du deadlocks i dit program. Men hvis du føler dig rimelig sikker på at det er OK det du laver, så skal der ikke være noget i vejen for at sætte CheckForIllegalCrossThreadCalls propertien til false.
Avatar billede lasserasch Juniormester
01. september 2010 - 18:02 #11
Om du opretter en tråd eller bruger en background worker er jo det samme. Men hvis du bruger en background worker har du jo en masse events du kan hooke dig op på = De funktioner du nu vil skrive selv.

Jeg kan ikke rigtig se idéen med ikke at gøre det.

Og om du skal oprette en ny tråd eller en ny background worker er jo lige nemt.

Men ja, du kan ikke kalde en anden funktion som skal opdatere UI direkte fra en backgroundworkers arbejdstråd, men dertil har man jo "ReportProgress" metoden. Og evented som bliver fyret af når den metode kaldes kører i samme tråd som UI og kan dermed opdatere UI.

Mvh.
Lasse

/Out
Avatar billede mjall0w Nybegynder
01. september 2010 - 20:06 #12
Tak aaberg, selvom det kom lidt for sent :/ Meget praktisk ihvertfald.
Selvom jeg har brugt adskille timer på at omskrive hele koden.

Kører det også i en backgroundthread, men selve problemet i spørgsmålet her var netop at jeg ikke kunne opdatere UI fra en anden tråd en backgroundworkeren.
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