Thread-Zugriff
lima-city → Forum → Programmiersprachen → Basic
aktualisieren
art
aufruf
beispiel
buchen
byte
code
ereignis
form
funktion
http
label
methode
objekt
problem
show
steuerelement
string
system
text
-
Hi Leute,
ich habe in VB.NET eine Klasse erstellt, welche ich über einen Threadzugriff aufrufe.
Dim NewHandler As New KLASSENNAME(Param1,Param2,...) Dim NewHandlerThread As New System.Threading.Thread(AddressOf NewHandler.FileRead) HandlerSendThread.IsBackground = True HandlerSendThread.Start()
Nun möchte ich in diesem Thread, welcher jedes Byte einer Datei in einer Art Schleife
For i as integer = 0 to File.Length \'Einlesen Next
ausliest.
Dannach soll er in einem anderen Fenster (Form) das Label1 verändern.
Er soll:
Form2.Label1.Text = i
ersetzen.
Aber das funktioniert noch nicht richtig. Der Text wird nicht verändert.
Habt ihr eine Lösung für mich?
Thx -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Nene, das ist hierbei nicht das Problem. Es geht darum, wenn ich angenommen von dem Thread aus eine Funktion, z.B.:
\'Die Funktion in Form2 sieht so aus: Public Sub ActualizeLabel2(ByVal Wert as String) Label1.Text = Wert End Sub \'Der Aufruf der Funktion über die Thread(-Klasse) Form2.ActualizeLabel2(WERT) \'WERT steht hierbei für i
Nun ist das Problem, wenn ich die Funktion in Form2 nun so umwandle:
Public Sub ActualizeLabel2(ByVal Wert as String) MessageBox.Show(Wert) Label1.Text = Wert End Sub
Dann wird in der MessageBox der richtige Wert angezeigt, aber Label1.Text wird nicht verändert.
Kennt ihr dafür eine Lösung? -
Ja ich kenne das Problem und die Lösung.
Das Problem liegt an einer ganz anderern Stelle als bisher vermutet:
\"Die Klasse [oder hier Funktion] sperrt sich aus Sicherheitsgründen selbst, bevor die Textaktualisierung erfolgt. Wenn andernfalls ein Aufrufer neuen Text zur Verfügung stellen würde, bevor der vorherige Text gespeichert worden wäre, köntte die Aktualiserung fehlschlagen.\"
Somit kann also der Text in der MessageBox gezeigt werden, aber nicht auf einem Steuerelement.
\"Windows-Steuerelemente sind nicht threadsicher. Dies bedeutet, dass es nicht sicher ist, ein Benutzeroberflächen-Steuerelement von einem anderen Thread aus zu aktualisieren als dem, in dem das Element erstellt wurde. Es ist möglich, ohne Schwierigkeiten mit Code zu arbeiten, der diese Warnung ignoriert, nur um nach Inbetriebnahme in der Praxis feststellen zu müssen, dass derselbe Code zu Problemen führt.\"
\"Dieses Problem ist nicht nur auf Code beschränkt, der in einem benutzerdefinierten Thread-Objekt ausgeführt wird. Es betrifft auch Code, der auf einen Rückruf oder ein Ereignis eines Thread-Objekts reagiert. Der Grund hierfür besteht darin, dass der Rückruf oder Ereignisbehandlungscode in dem Arbeits-Thread ausgeführt wird, der den Rückruf oder das Ereignis ausgelöst hat. Sie können dieses Problem glücklicherweise mithilfe der Methode Invoke lösen, die von allen .NET-Steuerelementen angeboten wird. Diese Methode erwartet einen MethodInvoker-Delegaten, der auf eine Methode ohne Parameter und Rückgabewert verweist. Der Code in dieser Methode wird in dem Benutzeroberflächen-Thread ausgeführt.\"
\"Diese [genannte] Technik funktioniert [nur] gut, wenn die Aktualisierungslogik nicht auf Variablen zugreifen mus. [Ansonsten] ... müssen [Sie] somit ein benutzerdefiniertes Wrapper-Objekt erstellen.\"
(C) Microsoft Press Deutschland
Beitrag geändert: 14.2.2008 19:00:23 von cbhp -
Könntest du mir evtl. einen Beispiel-Code dafür geben?
Ich habe das auf eine ähnlich Art probiert - aber bestimmt falsch.
thx -
Könntest du mir evtl. einen Beispiel-Code dafür geben?
Ich habe das auf eine ähnlich Art probiert - aber bestimmt falsch.
thx
Wenn du mehr verraten würdest, z.B. ob ein benutzerdefiniertes Wrapper-Objekt erforderlich ist oder nur die Invoker-Technik,
könnte man dir schon weiterhelfen.^^
Beitrag geändert: 14.2.2008 19:29:48 von cbhp -
Was ist denn nun ein Wrapper-Objekt??
Wird das angewendet, wenn ich noch andere Argumente (Überladungen) für eine \'Funktion\' angeben muss? Falls ja, dann brauche ich dafür einen Code.
Denn das ist mein Problem...
thx
Beitrag geändert: 14.2.2008 19:33:21 von lccserver -
lccserver schrieb:
Was ist denn nun ein Wrapper-Objekt??
Hatte ich im vorherigen Beitrag erklärt...
Jetzt darfst du aber selber lesen:
http://msdn2.microsoft.com/de-de/library/bb979513.aspx
Abschnitt: \"Benutzeroberflächencode zum richtigen Thread marshallen\"
Aufgabe: \"Sie möchten von einem anderen Thread aus ein Benutzeroberflächenelement eines Fensters aktualisieren.\"
http://msdn2.microsoft.com/de-de/library/bb979513.aspx#ID0EPH (Textmarke) -
Ich habe ein Buch von MS Press gekauft (50€), darin steht genau das selbe. ich habs nur eigenartigerweise nicht sofort verstanden...
-
Ich habe ein Buch von MS Press gekauft (50€), darin steht genau das selbe. ich habs nur eigenartigerweise nicht sofort verstanden...
Richtig! Wahrscheinlich \"Programmierrezepte, Visual Basic .NET\". Das Buch hab ich auch, es steht dort das meiste drin, was man üblicherweise braucht.
Wenn du etwas aus dem Buch nicht verstehst, solltest du aber deine Grundlagen erstmal verbessern. -
Nene, jetzt ist schon alles klar.
Ich hab das jetzt für mein Prog angewendet, es kommt aber ein Fehler:
System.InvalidOperationException: Invoke oder BeginInvoke kann für ein Steuerelement erst aufgerufen werden, wenn das Fensterhandle erstellt wurde.
FENSTERHANDLE? -
Nene, jetzt ist schon alles klar.
Ich hab das jetzt für mein Prog angewendet, es kommt aber ein Fehler:
System.InvalidOperationException: Invoke oder BeginInvoke kann für ein Steuerelement erst aufgerufen werden, wenn das Fensterhandle erstellt wurde.
FENSTERHANDLE?
Das heißt einfach, dass Invoke oder BeginInvoke erst nach dem Load-Ereignis der Form aufgerufen werden darf.
Du hast wahrscheinlich auf die Form falsch verwiesen...
Beitrag geändert: 14.2.2008 20:36:11 von cbhp -
Muss ich also erst
Form.Show()
\'ausführen\'?
Oder was soll ich machen??
Beitrag geändert: 14.2.2008 20:52:41 von lccserver -
Es kommt darauf an, WO du den Invoker aufrufst...
Übrigens tritt das Load-Ereignis bereits beim Erstellen der Form ein, also z.B. beim Neudeklarieren mit \"New\"
(Beispiel: Dim NeueForm1 As New Form1 löst das Load-Ereignis aus.)
Form.Show() löst das Shown-Ereignis aus.
Beitrag geändert: 14.2.2008 20:49:14 von cbhp -
Ich habe jetzt den Aufruf des Forms vor den Aufruf der \'Funktion\' gesetzt
Jetzt wird das Form scheinbar aktualisiert, aber dafür ist es ständig am aktualisieren und nichts wird mehr angezeigt (in diesem Form)...
Kann man das irgendwie unterbinden oder ne gute Lösung dafür finden? -
lccserver schrieb:
Ich habe jetzt den Aufruf des Forms vor den Aufruf der \\\'Funktion\\\' gesetzt
Jetzt wird das Form scheinbar aktualisiert, aber dafür ist es ständig am aktualisieren und nichts wird mehr angezeigt (in diesem Form)...
Kann man das irgendwie unterbinden oder ne gute Lösung dafür finden?
Scheint eher, dass du eine Schleife eingebaut hast in den Invoker oder einen Daueraufruf...
Das kann man sicher unterbinden... indem du den Auslöser für dieses Problem suchst, ich kenn deinen Code nicht. -
Wie ich bereits am Anfang beschrieben habe, ist der \'Auslöser\' ein Thread...Kann man da was machen?
-->Und: Was kann man da machen?
Beitrag geändert: 14.2.2008 21:01:34 von lccserver -
Man kann sicher was machen...
Aber wie rufst du denn den Thread auf? Rufst du ihn wiederholt auf? -
Ich lasse mit dem Thread jedes Byte einer Datei auslesen (in einer For-Next-Schleife):
For i as integer = 0 to File.Bytes \'AKTUALISIERUNG DES LABELS Next
Und da wird nach jedem Byte das Label aktualisiert (Label.Text = i.ToString())
Beitrag geändert: 14.2.2008 21:05:52 von lccserver -
Dann ist es ja kein Wunder, wenn die Form ständig aktualisiert wird.
Du weist ja dem Label in einem Bruchteil einer Sekunde mehrere tausend Zeichen zu...
Aber nach dem Aufruf \"Label.Text = i.ToString()\" solltest du ein \"Form.Refresh()\" einbauen.
Wenn das nicht hilft, dann nützt dir \"DoEvents()\" sicherlich.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage