none
Unterschied bei threadübergreifendem Control-Zugriff? RRS feed

  • Frage

  • Verständnisfrage:

    Gibts (a) vom Ergebnis und (b) vom Ablauf einen Unterschiede zwischen diesen beiden Codes:
    Dass bei dem ersten snippet das sub ResetTextBoxText nochmal aufgerufen wird ist mir klar, ich würde nur gerne wissen, ob der 2. Aufruf des ersten snippets sich im Ablauf vom 2. snippet unterscheidet.

        Private Sub ResetTextBoxText()
            If Me.TextBox1.InvokeRequired Then
                Me.TextBox1.Invoke(New MethodInvoker(AddressOf ResetTextBoxText))
            Else
                Me.TextBox1.ResetText()
            End If
        End Sub

    und:

    Private Sub ResetTextBoxText()
            If Me.TextBox1.InvokeRequired Then
                Me.TextBox1.Invoke(Sub() Me.TextBox1.ResetText())
            Else
                Me.TextBox1.ResetText()
            End If
        End Sub
    Ich habe den Eindruck, dass beides gleichwertig ist. Stimmt das?

    Vielen Dank

    TH


    Dienstag, 19. Januar 2016 16:33

Antworten

  • Hallo,


    MethodInvoker stellt einen einfachen Delegaten bereit..., Lambda Ausdrücke/anonyme Methoden ... können an Stellen verwendet werden, an denen die Verwendung eines Delegattypen gültig ist.

    Demnach ist das gleichwertig.

    Gruß



    • Bearbeitet K. Pater Dienstag, 19. Januar 2016 19:58
    • Als Antwort markiert Migration Sucks Dienstag, 19. Januar 2016 21:29
    Dienstag, 19. Januar 2016 19:54
  • Hi,
    beide Codeschnipsel sind in der Wirkungsweise identisch. Sobald aber zusätzliche Parameter ins Spiel kommen, kann man den MethodInvoker so nicht nutzen.

      Private Sub ResetTextBoxText2()
        If Me.TextBox1.InvokeRequired Then
          Me.TextBox1.Invoke(Sub()
                               Me.TextBox1.ResetText()
                             End Sub)
        Else
          Me.TextBox1.ResetText()
        End If
      End Sub


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut


    • Als Antwort markiert Migration Sucks Dienstag, 19. Januar 2016 21:29
    • Bearbeitet Peter Fleischer Freitag, 22. Januar 2016 03:06 fehlerhafte Bemerkung gelöscht.
    Dienstag, 19. Januar 2016 21:25
  • Hi,
    Hier mal eine kleine Demo mit einem Lambda und Parametern in eine Form mit TextBox1 und Button1:

    Public Class Form1
      Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim t As New Threading.Thread(New Threading.ThreadStart(AddressOf MyThread))
        t.Start()
      End Sub
    
      Private Sub MyThread()
        For I = 1 To 10
          SetTextBoxText(Now.ToLongTimeString)
          Threading.Thread.Sleep(500)
        Next
      End Sub
    
      Private Sub SetTextBoxText(par As String)
        If Me.TextBox1.InvokeRequired Then
          Me.TextBox1.Invoke(Sub(par2 As String)
                               Me.TextBox1.Text = par2
                             End Sub, par)
        Else
          Me.TextBox1.Text = par
        End If
      End Sub
    
    End Class


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Dienstag, 19. Januar 2016 22:04
  • Hi,
    über den Programmierstil kann man sich streiten. Der VB Compiler macht viel, um das Programmieren zu unterstützen. Alles unter dem Motto RAD. Der Lesbarkeit des Codes ist damit aber nicht unbedingt gedient. Das End Sub kann man weglassen, wenn der Lambda Ausdruck nur eine Anweisung ist. Mein Ding ist das aber nicht.

    Public Class Form1
      Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim t As New Threading.Thread(New Threading.ThreadStart(AddressOf MyThread))
        t.Start()
      End Sub
    
      Private Sub MyThread()
        For I = 1 To 10
          SetTextBoxText(Now.ToLongTimeString)
          Threading.Thread.Sleep(500)
        Next
      End Sub
    
      Private Sub SetTextBoxText(par As String)
        If Me.TextBox1.InvokeRequired Then
          Me.TextBox1.Invoke(Sub(par2 As String) Me.TextBox1.Text = par2, par)
        Else
          Me.TextBox1.Text = par
        End If
      End Sub
    
    End Class


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut


    Dienstag, 19. Januar 2016 22:10
  • Hallo,

    darfst Du auch. Denn Peters Annahmen gelten nur teilweise und allzu "puristisch" muss man mittlerweile nicht mehr sein.

    Zum einen ist die "alte" Schreibweise auf die ehemals mangelhafte Umsetzung von Lambda-Ausdrücken in Visual Basic 2008 zurückzuführen. Mittlerweile unterstützt Visual Basic das gesamte "Arsenal" wie es C# von Anfang tat - die Teams sind da zusammengewachsen.

    Das ein Lambda Sub(...) Ausdruck wie der MethodInvoker Delegat behandelt wird, ist ebenfalls darauf zurückzuführen; technisch unter dem Kapitel Kontravarianz abgehandelt. Was praktisch heißt, der Compiler baut so weit wie möglich den Ausdruck so um, dass er zu den Aufrufparametern passt.

    Um "Fehler" des Compilers zu vermeiden, sollte jedoch immer mit Option Strict On und Option Infer On (bei Lambda sowieso aktiv) gearbeitet werden.

    Gruß Elmar

    Mittwoch, 20. Januar 2016 09:26
    Beantworter

Alle Antworten

  • Hallo,


    MethodInvoker stellt einen einfachen Delegaten bereit..., Lambda Ausdrücke/anonyme Methoden ... können an Stellen verwendet werden, an denen die Verwendung eines Delegattypen gültig ist.

    Demnach ist das gleichwertig.

    Gruß



    • Bearbeitet K. Pater Dienstag, 19. Januar 2016 19:58
    • Als Antwort markiert Migration Sucks Dienstag, 19. Januar 2016 21:29
    Dienstag, 19. Januar 2016 19:54
  • Hi,
    beide Codeschnipsel sind in der Wirkungsweise identisch. Sobald aber zusätzliche Parameter ins Spiel kommen, kann man den MethodInvoker so nicht nutzen.

      Private Sub ResetTextBoxText2()
        If Me.TextBox1.InvokeRequired Then
          Me.TextBox1.Invoke(Sub()
                               Me.TextBox1.ResetText()
                             End Sub)
        Else
          Me.TextBox1.ResetText()
        End If
      End Sub


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut


    • Als Antwort markiert Migration Sucks Dienstag, 19. Januar 2016 21:29
    • Bearbeitet Peter Fleischer Freitag, 22. Januar 2016 03:06 fehlerhafte Bemerkung gelöscht.
    Dienstag, 19. Januar 2016 21:25
  • Vielen Dank K.Pater, das ist mehr als hilfreich!

    TH

    Dienstag, 19. Januar 2016 21:27

  •   
          Me.TextBox1.Invoke(Sub()
                               Me.TextBox1.ResetText()
                             End Sub)
      

    Vielen Dank Peter!

    Ich habe den Eindruck, dass das 'End Sub' optional ist.

    Dienstag, 19. Januar 2016 21:29
  •  Sobald aber zusätzliche Parameter ins Spiel kommen, kann man den MethodInvoker so nicht nutzen.

    Nur nochmal kurz: einen Lambda-Ausdruck aber offenbar schon (?)

    Dienstag, 19. Januar 2016 21:47
  • Hi,
    Hier mal eine kleine Demo mit einem Lambda und Parametern in eine Form mit TextBox1 und Button1:

    Public Class Form1
      Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim t As New Threading.Thread(New Threading.ThreadStart(AddressOf MyThread))
        t.Start()
      End Sub
    
      Private Sub MyThread()
        For I = 1 To 10
          SetTextBoxText(Now.ToLongTimeString)
          Threading.Thread.Sleep(500)
        Next
      End Sub
    
      Private Sub SetTextBoxText(par As String)
        If Me.TextBox1.InvokeRequired Then
          Me.TextBox1.Invoke(Sub(par2 As String)
                               Me.TextBox1.Text = par2
                             End Sub, par)
        Else
          Me.TextBox1.Text = par
        End If
      End Sub
    
    End Class


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Dienstag, 19. Januar 2016 22:04
  • Hi,
    über den Programmierstil kann man sich streiten. Der VB Compiler macht viel, um das Programmieren zu unterstützen. Alles unter dem Motto RAD. Der Lesbarkeit des Codes ist damit aber nicht unbedingt gedient. Das End Sub kann man weglassen, wenn der Lambda Ausdruck nur eine Anweisung ist. Mein Ding ist das aber nicht.

    Public Class Form1
      Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim t As New Threading.Thread(New Threading.ThreadStart(AddressOf MyThread))
        t.Start()
      End Sub
    
      Private Sub MyThread()
        For I = 1 To 10
          SetTextBoxText(Now.ToLongTimeString)
          Threading.Thread.Sleep(500)
        Next
      End Sub
    
      Private Sub SetTextBoxText(par As String)
        If Me.TextBox1.InvokeRequired Then
          Me.TextBox1.Invoke(Sub(par2 As String) Me.TextBox1.Text = par2, par)
        Else
          Me.TextBox1.Text = par
        End If
      End Sub
    
    End Class


    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut


    Dienstag, 19. Januar 2016 22:10
  • Danke nochmal Peter.
    Auch das würde ich anders schreiben:

    If Me.TextBox1.InvokeRequired Then
          Me.TextBox1.Invoke(Sub() Me.TextBox1.Text = par)   
    Kommt mir übersichtlicher vor (ich meine nun nicht das Weglassen von End Sub)


    Auch sowas funktioniert offenbar (hab ich in einem Programm verwendet):
    Me.Invoke(Sub() FrmMain.RecordIsEnded(true, rück))
    'für dieses Sub:
    Public Sub RecordIsEnded(withSucc As Boolean, ByVal msg As String) 




    Dienstag, 19. Januar 2016 22:38
  • HI,
    solange Du mit einem anonymen Inline Lambda arbeitest, funktionieren auch die kryptischen Abkürzungen. Mein Ding ist das nicht. Die Probleme entstehen, wenn erweitert und verändert werden soll.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Dienstag, 19. Januar 2016 23:19
  • Hallo,

    darfst Du auch. Denn Peters Annahmen gelten nur teilweise und allzu "puristisch" muss man mittlerweile nicht mehr sein.

    Zum einen ist die "alte" Schreibweise auf die ehemals mangelhafte Umsetzung von Lambda-Ausdrücken in Visual Basic 2008 zurückzuführen. Mittlerweile unterstützt Visual Basic das gesamte "Arsenal" wie es C# von Anfang tat - die Teams sind da zusammengewachsen.

    Das ein Lambda Sub(...) Ausdruck wie der MethodInvoker Delegat behandelt wird, ist ebenfalls darauf zurückzuführen; technisch unter dem Kapitel Kontravarianz abgehandelt. Was praktisch heißt, der Compiler baut so weit wie möglich den Ausdruck so um, dass er zu den Aufrufparametern passt.

    Um "Fehler" des Compilers zu vermeiden, sollte jedoch immer mit Option Strict On und Option Infer On (bei Lambda sowieso aktiv) gearbeitet werden.

    Gruß Elmar

    Mittwoch, 20. Januar 2016 09:26
    Beantworter
  • Hi Elmar,
    Du hast Recht mit Deinen Bemerkungen. Ich sehe nur bei meinen Schülern recht häufig, dass sie mit den Vereinfachungen nicht zurecht kommen, vor allem, wenn sie nicht regelmäßig professionell damit umzugehen haben. Mir gefällt deshalb auch VB besser als C#, weil man durch die "blumenreiche Umschreibung" der Sprachkonstrukte nicht so schnell den Überblick verliert im Gegensatz zu vielen Klammern.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Donnerstag, 21. Januar 2016 03:49
  • Hallo Peter,

    es ging mir dabei nicht um die "Optik" der Sprachsyntax - die mir persönlich relativ egal ist - sondern um den gebotenen Sprachumfang, bei dem in der Vergangenheit Visual Basic nicht immer mithalten konnte... was heute aber kein Thema mehr ist.

    What's New for Visual Basic in Visual Studio 2012

    What's New in Visual Basic 14 for Visual Studio 2015

    Ansonsten darf jeder mit seiner "Lieblingssprache" glücklich werden, wenn er so etwas braucht ;)

    Gruß Elmar

    Donnerstag, 21. Januar 2016 10:47
    Beantworter