Click here to Skip to main content
15,888,293 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello Everyone,

Can you help me with this one. Backgroundworker should make the Form responsive but my code is not doing that. Is there something wrong with the below code.

VB
Private Delegate Sub EncyptFilesDelegate()

Private Sub EncyptFiles()
    If Me.InvokeRequired Then
        Me.Invoke(New EncyptFilesDelegate(AddressOf EncyptFiles), New Object() {})
    Else
        'MORE CODE (Declaration, Create Folder, etc)
        For Each Filename As String In frmMain.OpenFileDialog1.FileNames
            FileCrypt(Filename, save & folders(Index) & "\" & file, UniqueID,  Crypt.CryptAction.Encrypt)
        Next
    End If
End Sub

Private Sub FileCrypt(ByVal InputFile As String, ByVal OutputFile As String, ByVal Password As String, ByVal Direction As Crypt.CryptAction)
    'MORE CODE (Declaration, Getting Key, etc)
    If Direction = Crypt.CryptAction.Encrypt Then
        CryptoStream = New Security.Cryptography.CryptoStream(Output, Rijndael.CreateEncryptor(Key, IV), Security.Cryptography.CryptoStreamMode.Write)
    Else
        CryptoStream = New Security.Cryptography.CryptoStream(Output, Rijndael.CreateDecryptor(Key, IV), Security.Cryptography.CryptoStreamMode.Write)
    End If
    Dim persecond As Long = 0
    Dim watch As New Stopwatch
    watch.Start()
    While Processed < FileLength
        CurrentBlock = Input.Read(Buffer, 0, 4096)
        CryptoStream.Write(Buffer, 0, CurrentBlock)
        Processed = Processed + CLng(CurrentBlock)
        'PROGRESSBAR
        TotalProcessed = TotalProcessed + CLng(CurrentBlock)
        If watch.ElapsedMilliseconds > 1000 Then
            ProgressBar1.Value = CInt((TotalProcessed / TotalLength) * 100)
            Me.Text = CInt((TotalLength - TotalProcessed) / persecond) & " seconds remaining"
            persecond = 0
            watch.Restart()
        End If
        persecond = persecond + CLng(CurrentBlock)
    End While
    watch.Stop()
    CryptoStream.Close()
    Input.Close()
    Output.Close()
End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    If Action = ProgressAction.Encypt Then
        Dim encypt As EncyptFilesDelegate = AddressOf EncyptFiles
        encypt.Invoke()
        MsgBox("Done")
    End If
End Sub

I try putting the FileCrypt inside the EncyptFiles but same result.

Thanks...
Posted

1 solution

The reason should be fairly obvious:
VB
Private Sub EncyptFiles()
    If Me.InvokeRequired Then
        Me.Invoke(New EncyptFilesDelegate(AddressOf EncyptFiles), New Object() {})
    Else
        'MORE CODE (Declaration, Create Folder, etc)
        For Each Filename As String In frmMain.OpenFileDialog1.FileNames
            FileCrypt(Filename, save & folders(Index) & "\" & file, UniqueID,  Crypt.CryptAction.Encrypt)
        Next
    End If
End Sub


  1. Your BackgroundWorker kicks off a new thread to raise the DoWork event;
  2. The DoWork event handler calls EncryptFiles;
  3. The EncryptFiles method notices that it's running on a background thread, and calls Invoke to move the work back to the UI thread;
  4. Work continues on the UI thread.


The solution is fairly simple:
  • Remove the InvokeRequired / Invoke code from your EncryptFiles method.
  • Use the BackgroundWorker's ReportProgress method[^] to pass the % progress and text back to the UI;
  • Handle the BackgroundWorker's ProgressChanged event[^] to update text and progress bar.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900