Einfrieren der Form verhindern...Hilfe!

  • VB.NET

Es gibt 68 Antworten in diesem Thema. Der letzte Beitrag () ist von MediaXtremely.

    Einfrieren der Form verhindern...Hilfe!

    Ich habe folgendes Problem wenn ich auf meinem Button klicke führt das Programm alles aus wunderbar, aber die Form friert ein.

    Wie kann ich das verhindern?
    Besser gesagt, wie kann ich das machen, dass ich die Form während das Programm arbeitet weiter bewegen?

    Hier der Coder:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    2. ListView1.Items(0).Focused = True
    3. ListView1.Items(0).Selected = True
    4. Dim i As Integer
    5. For i = 0 To ListView1.Items.Count - 1
    6. TextBox1.Text = ListView1.FocusedItem.Text
    7. TextBox3.Text = ListView1.FocusedItem.Text
    8. If TextBox1.Text.Contains("\") = True Then
    9. Dim Slash As Integer = InStrRev(TextBox1.Text, "\")
    10. TextBox3.Text = Mid(TextBox1.Text, Slash + 1)
    11. Else
    12. TextBox3.Text = TextBox1.Text
    13. End If
    14. If TextBox2.Text.Contains(TextBox3.Text) Then
    15. TextBox2.Text = TextBox2.Text.Replace(TextBox3.Text, "")
    16. TextBox2.Text = TextBox2.Text & GetLastWord(TextBox3.Text)
    17. Else
    18. TextBox2.Text = TextBox2.Text & GetLastWord(TextBox3.Text)
    19. End If
    20. If My.Computer.FileSystem.DirectoryExists(TextBox2.Text) Then
    21. For Each foundFile As String In My.Computer.FileSystem.GetFiles(TextBox2.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.*")
    22. File.SetAttributes(foundFile, FileAttributes.Normal)
    23. Next
    24. My.Computer.FileSystem.DeleteDirectory(TextBox2.Text, FileIO.DeleteDirectoryOption.DeleteAllContents)
    25. Application.DoEvents()
    26. My.Computer.FileSystem.CopyDirectory(ListView1.FocusedItem.Text, TextBox2.Text, False)
    27. Else
    28. My.Computer.FileSystem.CopyDirectory(ListView1.FocusedItem.Text, TextBox2.Text, False)
    29. End If
    30. TextBox2.Text = TextBox2.Text.Replace(TextBox3.Text, "")
    31. TextBox1.Text = ""
    32. TextBox3.Text = ""
    33. Dim ind As Integer = 0
    34. If (ListView1.SelectedItems.Count <> 0) Then
    35. ind = ListView1.SelectedItems.Item(0).Index
    36. End If
    37. If (ListView1.Items.Count <= ind + 1) Then
    38. ind = -1
    39. End If
    40. ListView1.SelectedItems.Clear()
    41. ListView1.Items.Item(ind + 1).Selected = True
    42. ListView1.Items.Item(ind + 1).Focused = True
    43. ListView1.Update()
    44. Next
    45. MsgBox("Ordner wurde kopiert.", MsgBoxStyle.Information, "Info")
    46. End Sub


    Währe sehr nett wenn mir einer helfen könnte...

    Ich bedanke mich schon mal im Voraus...

    MediaXtremely schrieb:

    falsch gedacht.

    Ja, ist es.
    Wenn du in der Küche gleichzeitig die Zwiebeln in der Pfanne umrühren musst, damit die nicht anbrennen, und Kartoffeln schneiden musst, dann brennt garantiert was an.
    Lösung ist, das "Kartoffeln schneiden" jemand anderes machen zu lassen (=den Vorgang "Kart. schneiden" als eigenen Thread deklarieren und starten). Wenn jemand anderes das übernimmt, kannst du seelenruhig die Zwiebeln umrühren.
    Soll heißen, der UI-Thread ist auch noch mit dem Zeichnen der Oberfläche beschäftigt. Gibst du ihm jetzt 'nen Brocken zum Bearbeiten, dann kann er nix zeichnen, und die Form friert ein.

    Rotherford postete nicht nur das Schlüsselwort, sondern dieses ist auf MSDN verlinkt. Lies dich dort ruhig mal rein, is'n Beispiel dabei.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „der_Kurt“ ()

    Du musst außerdem darauf achten, dass du im Thread mit Invokes arbeitest. Mit den Invokes bittest du also, dass der Kartoffelschneider dir die Kartoffelstücke gibt. Denn nehmen kannst du sie dir nicht einfach so. Invokes kannst du entweder mit Lambda-Audrücken ausführen oder halt mit der angegeben Funktion/Methode.

    rotherford schrieb:

    Code?


    Hier der Code:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Dim WithEvents BGW As New System.ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}
    2. Private Sub BGW_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
    3. ListView1.Items(0).Focused = True
    4. ListView1.Items(0).Selected = True
    5. Dim i As Integer
    6. For i = 0 To ListView1.Items.Count - 1
    7. TextBox1.Text = ListView1.FocusedItem.Text
    8. TextBox3.Text = ListView1.FocusedItem.Text
    9. If TextBox1.Text.Contains("\") = True Then
    10. Dim Slash As Integer = InStrRev(TextBox1.Text, "\")
    11. TextBox3.Text = Mid(TextBox1.Text, Slash + 1)
    12. Else
    13. TextBox3.Text = TextBox1.Text
    14. End If
    15. If TextBox2.Text.Contains(TextBox3.Text) Then
    16. TextBox2.Text = TextBox2.Text.Replace(TextBox3.Text, "")
    17. TextBox2.Text = TextBox2.Text & GetLastWord(TextBox3.Text)
    18. Else
    19. TextBox2.Text = TextBox2.Text & GetLastWord(TextBox3.Text)
    20. End If
    21. Me.Text = "Am kopieren..."
    22. Application.DoEvents()
    23. If My.Computer.FileSystem.DirectoryExists(TextBox2.Text) Then
    24. For Each foundFile As String In My.Computer.FileSystem.GetFiles(TextBox2.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.*")
    25. File.SetAttributes(foundFile, FileAttributes.Normal)
    26. Next
    27. My.Computer.FileSystem.DeleteDirectory(TextBox2.Text, FileIO.DeleteDirectoryOption.DeleteAllContents)
    28. Application.DoEvents()
    29. My.Computer.FileSystem.CopyDirectory(ListView1.FocusedItem.Text, TextBox2.Text, False)
    30. Else
    31. My.Computer.FileSystem.CopyDirectory(ListView1.FocusedItem.Text, TextBox2.Text, False)
    32. End If
    33. Me.Text = "Security Data"
    34. TextBox2.Text = TextBox2.Text.Replace(TextBox3.Text, "")
    35. TextBox1.Text = ""
    36. TextBox3.Text = ""
    37. Dim ind As Integer = 0
    38. If (ListView1.SelectedItems.Count <> 0) Then
    39. ind = ListView1.SelectedItems.Item(0).Index
    40. End If
    41. If (ListView1.Items.Count <= ind + 1) Then
    42. ind = -1
    43. End If
    44. ListView1.SelectedItems.Clear()
    45. ListView1.Items.Item(ind + 1).Selected = True
    46. ListView1.Items.Item(ind + 1).Focused = True
    47. ListView1.Update()
    48. Next
    49. End Sub
    50. Private Sub BGW_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BGW.ProgressChanged
    51. End Sub
    52. Private Sub BGW_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    53. MsgBox("Ordner wurde kopiert.", MsgBoxStyle.Information, "Info")
    54. End Sub
    Ok,
    Nur zum Test(!!) setz mal Control.CheckForIllegalThreadCrosses auf True.

    Wenn keine Fehlermeldung mehr kommt, vergiss diese Funktion ganz schnell und setze deine Control-Interaktionen mittels einem Lambda in ein Invoke().

    Liebe Grüße
    /nicht getestet

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „rotherford“ ()

    Der Quick-And-Dirty-Way wäre:


    VB.NET-Quellcode

    1. Me.invoke(Sub()
    2. ListView1.Items(0).Focused = True
    3. ListView1.Items(0).Selected = True
    4. Dim i As Integer
    5. For i = 0 To ListView1.Items.Count - 1
    6. TextBox1.Text = ListView1.FocusedItem.Text
    7. TextBox3.Text = ListView1.FocusedItem.Text
    8. If TextBox1.Text.Contains("\") = True Then
    9. Dim Slash As Integer = InStrRev(TextBox1.Text, "\")
    10. TextBox3.Text = Mid(TextBox1.Text, Slash + 1)
    11. Else
    12. TextBox3.Text = TextBox1.Text
    13. End If
    14. If TextBox2.Text.Contains(TextBox3.Text) Then
    15. TextBox2.Text = TextBox2.Text.Replace(TextBox3.Text, "")
    16. TextBox2.Text = TextBox2.Text & GetLastWord(TextBox3.Text)
    17. Else
    18. TextBox2.Text = TextBox2.Text & GetLastWord(TextBox3.Text)
    19. End If
    20. Me.Text = "Am kopieren..."
    21. Application.DoEvents()
    22. If My.Computer.FileSystem.DirectoryExists(TextBox2.Text) Then
    23. For Each foundFile As String In My.Computer.FileSystem.GetFiles(TextBox2.Text, FileIO.SearchOption.SearchAllSubDirectories, "*.*")
    24. File.SetAttributes(foundFile, FileAttributes.Normal)
    25. Next
    26. My.Computer.FileSystem.DeleteDirectory(TextBox2.Text, FileIO.DeleteDirectoryOption.DeleteAllContents)
    27. Application.DoEvents()
    28. My.Computer.FileSystem.CopyDirectory(ListView1.FocusedItem.Text, TextBox2.Text, False)
    29. Else
    30. My.Computer.FileSystem.CopyDirectory(ListView1.FocusedItem.Text, TextBox2.Text, False)
    31. End If
    32. Me.Text = "Security Data"
    33. TextBox2.Text = TextBox2.Text.Replace(TextBox3.Text, "")
    34. TextBox1.Text = ""
    35. TextBox3.Text = ""
    36. Dim ind As Integer = 0
    37. If (ListView1.SelectedItems.Count <> 0) Then
    38. ind = ListView1.SelectedItems.Item(0).Index
    39. End If
    40. If (ListView1.Items.Count <= ind + 1) Then
    41. ind = -1
    42. End If
    43. ListView1.SelectedItems.Clear()
    44. ListView1.Items.Item(ind + 1).Selected = True
    45. ListView1.Items.Item(ind + 1).Focused = True
    46. ListView1.Update()
    47. Next
    48. End Sub)


    Liebe Grüße
    /nicht getestet
    was aber vollkommener HurrDurr ist, da du dann den Thread auch nicht brauchst.

    Mach dir ne Sub ChangeText(textBox As TextBox, text As String)

    VB.NET-Quellcode

    1. Private Sub ChangeText(textBox As TextBox, text As String)
    2. textBox.text = text
    3. End Sub

    Dazu nen Delegaten:

    VB.NET-Quellcode

    1. Public Delegate Sub dlgChangeText(textBox As TextBox, text As String)

    Und ruf den dann mit

    VB.NET-Quellcode

    1. Dim dlgRef As dlgChangeText = new dlgChangeText(ChangeText)
    2. Me.Invoke(dlgRef(TextBox1, ListView1.FocusedItem.Text)

    So..das machst du immer nur dann, wenn du eine Property eines Controls verändern willst.
    Bei Auslesungen werden keine Probleme auftreten.

    Für die anderen Sachen musste entsprechend die Methoden erstellen.
    @Mediaxtreme:
    Nur Interessehalber: Was soll dieser Codeblock eigentlich bewirken? Vom ersten Blick sieht diese Sub wie ein Fünfzeiler aus.
    Die Funktionen des IO-Namespaces dürften nicht wirklich zum Einsatz gekommen sein. (GetFileNameWithoutExtension, GetFilename), ebenso wie String.Substring.
    Die aussagekräftigen Textboxen (1-3) machen den Quellcode für mich nämlich nicht nachvollziehbar. :(