Вопрос асинхронного вызова WPF - PullRequest
0 голосов
/ 15 июля 2010

Что не так в моем коде? Он не обновляет TextBox и ProgressBar при удалении файлов.

Imports System.Windows.Threading
Imports System.IO
Class MainWindow
    Private Sub bt_Click(ByVal sender As Object,
        ByVal e As RoutedEventArgs) Handles bt.Click

        Dim sb As New System.Text.StringBuilder
        Dim files = IO.Directory.EnumerateFiles(
         My.Computer.FileSystem.SpecialDirectories.Temp, "*.*",
         SearchOption.TopDirectoryOnly)

        Dim count = files.Count

        pb.Minimum = 0
        pb.Maximum = count

        For i = 0 To count - 1
            Dim f = files(i)

            Dispatcher.BeginInvoke(
             New Action(Of String, Integer)(
             Sub(str, int)
                 tb.SetValue(TextBox.TextProperty, str)
                 pb.SetValue(ProgressBar.ValueProperty, int)
             End Sub),
            DispatcherPriority.Send,
            f, i + 1)

            Try
                File.Delete(f)
            Catch ex As Exception
                sb.AppendLine(f)
            End Try

            Dim exceptions = sb.ToString
            Stop
        Next

    End Sub
End Class

1 Ответ

0 голосов
/ 16 июля 2010

Я получил это, работая с объектом BackgroundWorker. Это помещает вашу работу в фоновый поток с вызовами для обновления пользовательского интерфейса, проходящими через событие ProgressChanged. Я также использовал Invoke вместо BeginInvoke в рабочем цикле, что заставляет цикл ждать обновления пользовательского интерфейса, прежде чем продолжить.

Imports System.ComponentModel
Imports System.IO

Class MainWindow
    Private WithEvents bw As New BackgroundWorker

    Private Sub Button1_Click(ByVal sender As System.Object,
            ByVal e As RoutedEventArgs) Handles btn.Click
        pb.Minimum = 0
        pb.Maximum = 100
        bw.WorkerReportsProgress = True
        bw.RunWorkerAsync()
    End Sub

    Private Sub bw_DoWork(ByVal sender As Object,
             ByVal e As DoWorkEventArgs) Handles bw.DoWork
        Dim sb As New System.Text.StringBuilder
        Dim files = IO.Directory.EnumerateFiles(
         My.Computer.FileSystem.SpecialDirectories.Temp, "*.*",
         SearchOption.TopDirectoryOnly)

        Dim count = files.Count
        Me.Dispatcher.BeginInvoke(Sub()
                                      tb.Text = "SOMETHING ELSE"
                                  End Sub)
        For i = 0 To count - 1
            Dim f = files(i)
            Dim myI = i + 1
            Me.Dispatcher.Invoke(
                           Sub()
                               bw.ReportProgress(CInt((myI / count) * 100), f)
                           End Sub)

            'Try 
            '    File.Delete(f) 
            'Catch ex As Exception 
            '    sb.AppendLine(f) 
            'End Try 

            Dim exceptions = sb.ToString
            'Stop 
        Next
    End Sub


    Private Sub bw_ProgressChanged(
             ByVal sender As Object, 
             ByVal e As ProgressChangedEventArgs) Handles bw.ProgressChanged
        Dim fString As String = TryCast(e.UserState, String)
        Me.Dispatcher.BeginInvoke(Sub()
                                      tb.Text = fString
                                  End Sub)
    End Sub
End Class
...