Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Values To and From Background Worker

I'm a self-taught novice experimenting with the Rijndael encryption algorithm, I've previously got it to work very well, but since trying to get the encryption to run on a background worker to free-up the the form for the user I've ran into numerous issues.

Firstly I tried just placing the byval's I used in my previous code into the background worker, but I got an error with it not being compatible -- Specifically the ByVal Direction As CryptoAction.

So to be clear, I was trying something like this:

Private Sub bw_DoWork(ByVal sender As Object,ByVal strInputFile As String,
                                     ByVal strOutputFile As String,
                                     ByVal bytKey() As Byte,
                                     ByVal bytIV() As Byte,
                                     ByVal Direction As CryptoAction, ByVal e As DoWorkEventArgs)


    Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)

    For i = 1 To 1
        If bw.CancellationPending = True Then
            e.Cancel = True
            Exit For
        Else

            'Encryption code goes here. 
end sub 

But as I said, I was being told the Direction As CrytoAction was not compatible. In teh intrest of completness, that sub was:

Private Enum CryptoAction
        'Define the enumeration for CryptoAction.
        ActionEncrypt = 1
        ActionDecrypt = 2
    End Enum

So in order to get the code to work I done this, and I think this is why my encrypted files decrypt into a unreadable file and I sometimes get the error: Padding is invalid and cannot be removed. when closing the file stream.

So I declared the bytkey, byIV, Direction and the rest in my Public Class, this, as I said let the code run. But I can get the file back once encrypted. My thinking is that when my code references the functions, instead of receiving the returned value, it's receiving an empty string?

Here's the code that references the functions which generate the keys, just to be clear at what I'm meaning.

                 Select Case Direction
                        Case CryptoAction.ActionEncrypt
                            csCryptoStream = New CryptoStream(fsOutput, _
                            cspRijndael.CreateEncryptor(bytKey, bytIV), _
                            CryptoStreamMode.Write)

                    Case CryptoAction.ActionDecrypt
                        csCryptoStream = New CryptoStream(fsOutput, _
                        cspRijndael.CreateDecryptor(bytKey, bytIV), _
                        CryptoStreamMode.Write)
                End Select

So, my question is, am I right that the code is referencing nulled values from the declarations, or would the code still reference the functions? And, is it possible add the ByVal CryptoStream into the background worker?

My sincerest appologise for the size of my question, I've looked everywhere for a solution but can't find anything relevant.

like image 656
user3516240 Avatar asked Oct 20 '22 20:10

user3516240


1 Answers

You can't change the signature of the DoWork event, but it contains a generic Object for you to use (called e.Argument). Define a custom class to contain all the data you want to move to and from the BackgroundWorker.

Option Strict On

Public Class Form1
  Class MyParameters
    Friend Input As Integer
    Friend Output As Integer
    Friend Message As String
  End Class

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim m As New MyParameters
    m.Input = 1
    ListBox1.Items.Add("Button1_Click")
    ListBox1.Items.Add("    Input: " & m.Input)
    BackgroundWorker1.WorkerReportsProgress = True
    BackgroundWorker1.RunWorkerAsync(m)   'this triggers BackgroundWorker1_DoWork. When finished, BackgroundWorker1_RunWorkerCompleted() is raised
  End Sub

  Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Dim m As MyParameters = DirectCast(e.Argument, MyParameters) 'Convert the generic Object back into a MyParameters object
    m.Message = "Progress report"
    BackgroundWorker1.ReportProgress(50, m) 'this triggers BackgroundWorker1.ProgressChanged. N.B. We could actually use a different class here, but we'll re-use the same class for simplicity
    m.Output = m.Input + 1
    e.Result = m
    'fun continues at BackgroundWorker1_RunWorkerCompleted
  End Sub

  Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    ListBox1.Items.Add("BackgroundWorker1_ProgressChanged")
    Dim m As MyParameters = DirectCast(e.UserState, MyParameters) 'Convert the generic Object back into a MyParameters object
    ListBox1.Items.Add("    " & m.Message & " " & e.ProgressPercentage.ToString)
  End Sub

  Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    ListBox1.Items.Add("BackgroundWorker1_RunWorkerCompleted")
    Dim m As MyParameters = DirectCast(e.Result, MyParameters) 'Convert the generic Object back into a MyParameters object
    ListBox1.Items.Add("    Output: " & m.Output)
  End Sub
End Class
like image 166
SSS Avatar answered Oct 22 '22 21:10

SSS