Stabiler/Zuverlässiger Timer oder Thread + Checkforillegalcrossthreadcalls?

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

    Stabiler/Zuverlässiger Timer oder Thread + Checkforillegalcrossthreadcalls?

    Hallo,
    Ich wollte nur mal eine Allgemeine Frage stellen und zwar :
    Was arbeitet zuverlässiger / stabiler ein Timer oder ein Thread mit Checkforillegalcrossthreadcalls = false ?



    Mfg Kevin.
    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
    besser als Delegates finde ich jedoch PostAsyncs :P(damit arbeitet auch der BackgroundWorker, damit z.B. das ProgressChanged Event wieder im GUI Thread ausgeführt wird...)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    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 wird
    Ich 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 Invoke ;)
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    doch nicht aus einer Klasse heraus?(nat. ohne ein Control gegeben zu haben), wenn es geht dann bin ich bereit zu lernen(wäre über ein Beispiel froh ;))
    Ich 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

    1. Public Class MyEventFireClass
    2. Public Delegate Sub MyEventHandler(ByVal sender As Object, ByVal e As System.EventArgs)
    3. Public Event ThreadCompleted As MyEventHandler
    4. Private Sub InvokeEvent(ByVal Sender As Object, ByVal e As System.EventArgs, ByVal EventDel As System.Delegate)
    5. Dim eFired As Boolean = False
    6. If EventDel IsNot Nothing Then
    7. For Each singleDel As System.Delegate In EventDel.GetInvocationList
    8. eFired = False
    9. Try
    10. Dim syncInvoke As System.ComponentModel.ISynchronizeInvoke _
    11. = CType(singleDel.Target, System.ComponentModel.ISynchronizeInvoke)
    12. If syncInvoke IsNot Nothing And syncInvoke.InvokeRequired Then
    13. eFired = True
    14. syncInvoke.Invoke(singleDel, New Object() {Sender, e})
    15. Else
    16. eFired = True
    17. singleDel.DynamicInvoke(New Object() {Sender, e})
    18. End If
    19. Catch ex As System.Reflection.TargetInvocationException
    20. If Not eFired Then singleDel.DynamicInvoke(New Object() {Sender, e})
    21. End Try
    22. Next
    23. End If
    24. End Sub
    25. Private _str As String
    26. Public Property Smth() As String
    27. Get
    28. Return _str
    29. End Get
    30. Set(ByVal value As String)
    31. _str = value
    32. End Set
    33. End Property
    34. Public Sub StartCalcAsync()
    35. Dim t As New Threading.Thread(AddressOf ThreadProcedure)
    36. t.Start()
    37. End Sub
    38. Private Sub ThreadProcedure()
    39. Dim a = 0
    40. Do Until a = 10
    41. Threading.Thread.Sleep(100)
    42. a += 1
    43. Loop
    44. Smth = "Ready Rocksteady"
    45. InvokeEvent(Me, New System.EventArgs, ThreadCompletedEvent)
    46. End Sub
    47. End Class



    Beispielanwendung:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form2
    2. Friend WithEvents b As New Button
    3. Private WithEvents mye As MyEventFireClass
    4. Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    5. Me.Controls.Add(b)
    6. End Sub
    7. Private Sub b_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles b.Click
    8. mye = New MyEventFireClass
    9. mye.StartCalcAsync()
    10. End Sub
    11. Private Sub mye_ThreadCompleted(ByVal sender As Object, ByVal e As System.EventArgs) Handles mye.ThreadCompleted
    12. b.Text = mye.Smth
    13. b.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink
    14. b.AutoSize = True
    15. End Sub
    16. 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 bewerten :P
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---