Async ProcessBar not working

Charles He-MSFT 96 Reputation points Microsoft Employee
2020-02-25T07:55:08.207+00:00

Source thread: Async ProgressBar not working, answered by Peter Fleischer.

I'm trying to set up an async read of a bunch of files with a ProgressBar, but it doesn't work.

Here is my MainWindow:
Class MainWindow
Dim TheProgress As Progress(Of Integer)
Dim ProgCntr As Integer
Dim CToken As CancellationToken

And the process code:

Public Async Sub StartFntRead(TheFiles As List(Of IO.FileInfo), TheTxt As String)   
        With Me  
            .ProgBar.Value = 0  
            .ProgBar.Maximum = TheFiles.Count  
            .ProgBar.Visibility = Windows.Visibility.Visible  
        End With  
        With Me.LablProgText  
            .Content = TheTxt  
            .Visibility = Windows.Visibility.Visible  
        End With  
        ProgCntr = 0  
        CToken = New CancellationToken  
        TheProgress = New Progress(Of Integer)(AddressOf ReportProgress)  
        Await ReadFntFiles(CToken, TheFiles, TheProgress)  
        Me.ProgBar.Visibility = Windows.Visibility.Hidden  
        Me.LablProgText.Visibility = Windows.Visibility.Hidden  
    End Sub  
  
    Public Async Function ReadFntFiles(CTokn As CancellationToken, TheFiles As List(Of IO.FileInfo), Prog As IProgress(Of Integer)) As Task(Of Integer)  
        Dim Fnt As FntData  
        For Each AFile In TheFiles  
            ProgCntr += 1  
            Prog.Report(ProgCntr)  
            Fnt = New FontUtils.FntData With {.FName = AFile.FullName}  
            Select Case System.IO.Path.GetExtension(AFile.FullName).ToUpper  
                Case Is = ".TTF", ".OTF"  
                    Call FontUtils.ReadTTOT(Fnt)  
                Case Is = ".PFM"  
                    Call FontUtils.ReadT1(Fnt)  
            End Select  
            If Fnt.IsOK Then  
                TheAvailFnts.Add(Fnt)  
            Else  
                FntErrsSet.Fnts.Add(Fnt)  
            End If  
        Next AFile  
    End Function  
    Public Sub ReportProgress(ByVal ProgNum As Integer)  
        Me.ProgBar.Value = ProgNum  
    End Sub  

To start processing files, call the StartFntRead method:

Call StartFntRead(TheFiles, "Reading font files")  

Any suggestion?

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,695 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Alex Li-MSFT 1,096 Reputation points
    2020-02-25T08:00:07.347+00:00

    Hi,

    Welcome to our Microsoft Q&A platform!

    You can try the following demo:

     Imports System.IO  
    Imports System.Threading  
      
    Public Class Window1  
      
      Private ProgCntr As Integer  
      Private CToken As CancellationTokenSource  
      Private TheProgress As New Progress(Of Integer)  
      
      Private Sub Button_Click(sender As Object, e As RoutedEventArgs)  
        Dim listFI As List(Of FileInfo)  
        listFI = (From item In My.Computer.FileSystem.GetFiles("c:\temp") Select New FileInfo(item)).ToList  
        StartFntRead(listFI, "txt")  
      End Sub  
      
      Public Async Sub StartFntRead(TheFiles As List(Of IO.FileInfo), TheTxt As String)  
        With Me  
          .ProgBar.Value = 0  
          .ProgBar.Maximum = TheFiles.Count  
          .ProgBar.Visibility = Windows.Visibility.Visible  
        End With  
        With Me.LablProgText  
          .Content = TheTxt  
          .Visibility = Windows.Visibility.Visible  
        End With  
        CToken = New CancellationTokenSource()  
        Dim ct As CancellationToken = CToken.Token  
        AddHandler TheProgress.ProgressChanged, Sub(s, n)  
                                                  ProgBar.Value = n  
                                                End Sub  
        Await Task.Run(Sub() ReadFntFiles(TheFiles, TheProgress, CToken.Token), CToken.Token)  
        MsgBox("Back after ReadFntFiles")  
        Me.ProgBar.Visibility = Windows.Visibility.Hidden  
        Me.LablProgText.Visibility = Windows.Visibility.Hidden  
      End Sub  
      
      Public Sub ReadFntFiles(TheFiles As List(Of IO.FileInfo), ByVal progress As IProgress(Of Integer), ByVal ct As CancellationToken)  
      
        ' comment out for demo purposes  
      
        'Dim Fnt As FntData  
        '' with following method you can create a async thread and return awaitable object  
        'Dim ProgCntr As Integer = 0  
        'For Each AFile In TheFiles  
        '  If ct.IsCancellationRequested Then Exit For  
        '  ProgCntr += 1  
        '  progress.Report(ProgCntr)  
        '  Fnt = New FontUtils.FntData With {.FName = AFile.FullName}  
        '  Select Case System.IO.Path.GetExtension(AFile.FullName).ToUpper  
        '    Case Is = ".TTF", ".OTF"  
        '      Call FontUtils.ReadTTOT(Fnt)  
        '    Case Is = ".PFM"  
        '      Call FontUtils.ReadT1(Fnt)  
        '  End Select  
        '  If Fnt.IsOK Then  
        '    TheAvailFnts.Add(Fnt)  
        '  Else  
        '    FntErrsSet.Fnts.Add(Fnt)  
        '  End If  
        '  'MsgBox(Fnt.DisplayName)  
        'Next AFile  
      
        ' simalation of work  
        For i = 1 To 100  
          If ct.IsCancellationRequested Then Exit For  
          Thread.Sleep(100) ' simulate working time  
          progress.Report(i)  
        Next  
      
      End Sub  
      
    End Class  
    

    Thanks.

    0 comments No comments