Stabiler/Zuverlässiger Timer oder Thread + Checkforillegalcrossthreadcalls?
- VB.NET
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.
-
-
-
Um Tsuyos Antwort etwas auszuführen:
Setze niemals CheckForIllegalCrossThreadCalls auf False! Nimm Delegates.
Ich würde sagen, dass ein Thread zuverlässiger ist. Auf jeden Fall dann, wenn du Dinge tust, die nicht im UI-Thread laufen müssen. Zugriffe auf das UI müssen bei Threading über Delegates und BeginInvoke() durchgeführt werden.
Viele Grüße, Phil. -
Gutelaunetyp schrieb:
Was arbeitet zuverlässiger / stabiler ein Timer oder ein Thread mit Checkforillegalcrossthreadcalls = false ?
Weder, noch. Wenn du Multithreading verwendest und auf Controls aus einem anderen Thread zugreifen musst, brauchst du einen Wrapper für den entsprechenden Aufruf, der dir die Daten an den richtigen Thread marshallt. CheckForIllegalCrossThreadCalls hat seine Berechtigung und sollte IMMER True sein, da es bei unerlaubten direkten Zugriffen leicht zu Deadlocks kommt, die deine Anwendung unbedienbar machen. Ein Timer ist sowieso keine Lösung für den Zweck, den die meisten User hier erreichen wollen. In diesem Zusammenhang möchte ich auch noch loswerden, dass du von Application.DoEvents() Abstand nehmen solltest. Der angesprochene Wrapper ist beim Multithreading die einzige vernünftige Lösung.Gruß
hal2000
-
-
-
irgendwer hat da mal ein(fast Fehlerfreies - musste einfach ein paar Fehler rein machen) Bsp. gepostet: [VB.NET] Form-Anwendung laufen lassen, bis anderer Prozess beendet wirdIch wollte auch mal ne total überflüssige Signatur:
---Leer--- -
jvbsl schrieb:
PostAsyncs
Du meinst damit wohl ein PostMessage mit dem entsprechenden Thread als Ziel, oder? Das Codebeispiel, das im vorigen Post verlinkt wird, zielt auf ein ganz anderes Thema ab (und ist dazu, wenn ich das sagen darf, nicht gerade die beste Lösung auch für die dortige Frage; eher quick&dirty). Im Entfernten hängt das natürlich alles voneinander ab - aber dafür muss einfach das Hintergrundwissen vorhanden sein, wovon wir (@jvbsl) nicht ausgehen sollten.
Weitere Informationen dazu gibts in diesem Thread (inkl. der dort weiterverlinkten Seiten): social.msdn.microsoft.com/foru…6-4b4d-a2e0-3948e256b899/Gruß
hal2000
-
ja ich meine PostMessage und Async meint ich aufgrund von den Threads, weil es dann ja auch Asynchron ist...
quick&dirty kommt stark darauf an, PostMessage ist sehr wohl sauber, aber die Lösung mit ner endlosschleife in einem Thread ist wohl eher hier das Problem
Aber hier war das sehr wohl angebracht, bei einem Invoke wird ja darauf gewartet, bis die entsprechende Methode ausgeführt wurde(Lösung, dass der Thread nicht wartet->BeginInvoke oder PostMessage ;))Ich wollte auch mal ne total überflüssige Signatur:
---Leer--- -
jvbsl schrieb:
aber die Lösung mit ner endlosschleife in einem Thread ist wohl eher hier das Problem
...der Thread selbst ist das Problem - er hält die Anwendung im Hintergrund aktiv, welche aber keinerlei Eingaben verarbeiten kann, da sich der Thread in einer Endlosschleife befindet. Besser wäre in diese Fall Application.Run() ohne Parameter, damit der Prozess mit Application.Exit() oder extern sauber beendet werden kann.
PostMessage ist hier schon angebracht - aber warum so umständlich? Control.BeginInvoke() verwendet diese Funktion intern - das muss nicht selbst implementiert werden.Gruß
hal2000
-
das sollte doch in einem extra Thread sein?!^^ Und meinem Code zufolge wird das Application.Exit ebenfalls aufgerufen und somit sauber beendet...
PostMessage ist hier schon angebracht - aber warum so umständlich? Control.BeginInvoke() verwendet diese Funktion intern - das muss nicht selbst implementiert werden.
Da man Threads oft auch in Klassen verwendet und dort will man evtl. auch ein Event im GUI Thread aufrufen, dies geht aus einer Klasse ohne das externe Control nicht mit InvokeIch wollte auch mal ne total überflüssige Signatur:
---Leer--- -
-
-
HI, ich habe vor einiger Zeit danach gesucht und damals etwas gefunden. Es war ähnlich aufgebaut wie ich das jetzt hier habe.
Leider habe ich den Link zu dieser Quelle nicht mehr. Lediglich den gefundenen und von mir etwas bearbeiteten Code den ich damals eingesetzt hatte:
Ich habe im Beispiel auf Custom Event Args verzichtet.
Klasse:
Spoiler anzeigen
VB.NET-Quellcode
- Public Class MyEventFireClass
- Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
- Public Event ThreadCompleted As MyEventHandler
- Private Sub InvokeEvent(ByVal Sender As Object, ByVal e As System.EventArgs, ByVal EventDel As System.Delegate)
- Dim eFired As Boolean = False
- If EventDel IsNot Nothing Then
- For Each singleDel As System.Delegate In EventDel.GetInvocationList
- eFired = False
- Try
- Dim syncInvoke As System.ComponentModel.ISynchronizeInvoke _
- = CType(singleDel.Target, System.ComponentModel.ISynchronizeInvoke)
- If syncInvoke IsNot Nothing And syncInvoke.InvokeRequired Then
- eFired = True
- syncInvoke.Invoke(singleDel, New Object() {Sender, e})
- Else
- eFired = True
- singleDel.DynamicInvoke(New Object() {Sender, e})
- End If
- Catch ex As System.Reflection.TargetInvocationException
- If Not eFired Then singleDel.DynamicInvoke(New Object() {Sender, e})
- End Try
- Next
- End If
- End Sub
- Private _str As String
- Public Property Smth() As String
- Get
- Return _str
- End Get
- Set(ByVal value As String)
- _str = value
- End Set
- End Property
- Public Sub StartCalcAsync()
- Dim t As New Threading.Thread(AddressOf ThreadProcedure)
- t.Start()
- End Sub
- Private Sub ThreadProcedure()
- Dim a = 0
- Do Until a = 10
- Threading.Thread.Sleep(100)
- a += 1
- Loop
- Smth = "Ready Rocksteady"
- InvokeEvent(Me, New System.EventArgs, ThreadCompletedEvent)
- End Sub
- End Class
Beispielanwendung:
Spoiler anzeigen
VB.NET-Quellcode
- Public Class Form2
- Friend WithEvents b As New Button
- Private WithEvents mye As MyEventFireClass
- Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
- Me.Controls.Add(b)
- End Sub
- Private Sub b_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles b.Click
- mye = New MyEventFireClass
- mye.StartCalcAsync()
- End Sub
- Private Sub mye_ThreadCompleted(ByVal sender As Object, ByVal e As System.EventArgs) Handles mye.ThreadCompleted
- b.Text = mye.Smth
- b.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink
- b.AutoSize = True
- End Sub
- End Class
Das ist meine Signatur und sie wird wunderbar sein!Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Mono“ ()
-
hui schon wieder was gelernt ;), aber mit einem PostMessage ist das noch wesentlich kürzer, was jetzt davon besser ist kann ich selbst nicht beurteilen, aber wenn PostMessage beim BackgroundWorker verwendet wird, glaube ich nicht, dass es Falsch, bzw. schlecht ist...Was nun besser ist, müsste man wohl irgendwie mal bewertenIch wollte auch mal ne total überflüssige Signatur:
---Leer---
-
Ähnliche Themen
-
joniator11 - - Sonstige Problemstellungen