Help with modifying example for single file (

May 15, 2010 at 8:10 PM

I'm trying to modify one of the examples to zip a single file rather than a whole folder.
Im getting cross thread exeptions while trying to update the label with the current % and the final compression ratio (Same as original examples)

I've removed everything except the kickoff button, progressbar2, status label and Cancel button.

So far I have:


Imports System.IO
Imports Ionic.Zip
Imports System.Threading

Public Class Form1
    ' Delegates for invocation of UI from other threads
    Private Delegate Sub SaveEntryProgress(ByVal e As SaveProgressEventArgs)
    Private Delegate Sub ButtonClick(ByVal sender As Object, ByVal e As EventArgs)

    Private _workerThread As Thread
    Private _saveCanceled As Boolean
    Private _totalBytesAfterCompress As Long
    Private _totalBytesBeforeCompress As Long
    'Private _nFilesCompleted As Integer
    Private _progress2MaxFactor As Integer
    'Private _entriesToZip As Integer

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnZipUp.Click
    End Sub

    Private Sub KickoffZipup()
        Dim fileName As String = "C:\Test\test.txt"
        Me._saveCanceled = False
        Me._totalBytesAfterCompress = 0
        Me._totalBytesBeforeCompress = 0
        Me.btnZipUp.Enabled = False
        Me.btnZipUp.Text = "Zipping..."
        Me.btnCancel.Enabled = True
        Me.lblStatus.Text = "Zipping..."
        Dim options As New WorkerOptions
        options.ZipName = "C:\Test\"
        options.File = fileName
        Me._workerThread = New Thread(AddressOf DoSave)
        Me._workerThread.Name = "Zip Saver thread"
        Me.Cursor = Cursors.WaitCursor
    End Sub

    Private Sub DoSave(ByVal p As Object)
        Dim options As WorkerOptions = TryCast(p, WorkerOptions)
            Using zip1 As ZipFile = New ZipFile
                AddHandler zip1.SaveProgress, New EventHandler(Of SaveProgressEventArgs)(AddressOf Me.zip1_SaveProgress)
            End Using
        Catch exc1 As Exception
            MessageBox.Show(String.Format("Exception while zipping: {0}", exc1.Message))
            Me.btnCancel_Click(Nothing, Nothing)
        End Try
    End Sub

    Private Sub zip1_SaveProgress(ByVal sender As Object, ByVal e As SaveProgressEventArgs)
        Select Case e.EventType
            Case ZipProgressEventType.Saving_AfterWriteEntry
                Exit Select
            Case ZipProgressEventType.Saving_Completed
                Exit Select
            Case ZipProgressEventType.Saving_EntryBytesRead
                Exit Select
        End Select
        If Me._saveCanceled Then
            e.Cancel = True
        End If
    End Sub

    Private Sub StepArchiveProgress(ByVal e As SaveProgressEventArgs)
        If Not Me._saveCanceled Then
            Me._totalBytesAfterCompress = (Me._totalBytesAfterCompress + e.CurrentEntry.CompressedSize)
            Me._totalBytesBeforeCompress = (Me._totalBytesBeforeCompress + e.CurrentEntry.UncompressedSize)
            Me.ProgressBar2.Value = Me.ProgressBar2.Maximum = 1
        End If
    End Sub

    Private Sub SaveCompleted()
        If Me.lblStatus.InvokeRequired Then
            Me.lblStatus.Invoke(New MethodInvoker(AddressOf SaveCompleted))
            Me.lblStatus.Text = String.Format("Done, Compressed to, {1:N0}% of original", ((100 * Me._totalBytesAfterCompress) / CDbl(Me._totalBytesBeforeCompress)))
        End If
    End Sub

    Private Sub StepEntryProgress(ByVal e As SaveProgressEventArgs)
        If Me.ProgressBar2.InvokeRequired Then
            Me.ProgressBar2.Invoke(New SaveEntryProgress(AddressOf Me.StepEntryProgress), New Object() {e})
        ElseIf Not Me._saveCanceled Then
            If (Me.ProgressBar2.Maximum = 1) Then
                Dim entryMax As Long = e.TotalBytesToTransfer
                Dim absoluteMax As Long = &H7FFFFFFF
                Me._progress2MaxFactor = 0
                Do While (entryMax > absoluteMax)
                    entryMax = (entryMax / 2)
                    Me._progress2MaxFactor += 1
                If (CInt(entryMax) < 0) Then
                    entryMax = (entryMax * -1)
                End If
                Me.ProgressBar2.Maximum = CInt(entryMax)
                'Me.lblStatus.Text = String.Format("{0} of {1} files...({2})", (Me._nFilesCompleted + 1), Me._entriesToZip, e.CurrentEntry.FileName)
            End If
            Dim xferred As Integer = CInt((e.BytesTransferred >> Me._progress2MaxFactor))
            Me.ProgressBar2.Value = IIf((xferred >= Me.ProgressBar2.Maximum), Me.ProgressBar2.Maximum, xferred)
        End If
    End Sub

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        If Me.lblStatus.InvokeRequired Then
            Me.lblStatus.Invoke(New ButtonClick(AddressOf Me.btnCancel_Click), New Object() {sender, e})
            Me._saveCanceled = True
            Me.lblStatus.Text = "Canceled..."
        End If
    End Sub

    Private Sub ResetState()
        Me.btnCancel.Enabled = False
        Me.btnZipUp.Enabled = True
        Me.btnZipUp.Text = "Zip it!"
        Me.ProgressBar2.Value = 0
        Me.Cursor = Cursors.Default
        If Not Me._workerThread.IsAlive Then
        End If
    End Sub

    Private Sub SetProgressBars()
        If Me.ProgressBar2.InvokeRequired Then
            Me.ProgressBar2.Invoke(New MethodInvoker(AddressOf SetProgressBars))
            Me.ProgressBar2.Value = 0
            Me.ProgressBar2.Minimum = 0
            Me.ProgressBar2.Maximum = 1
            Me.ProgressBar2.Step = 2
        End If
    End Sub

End Class

Public Class WorkerOptions
    ' Fields
    'Public Comment As String
    'Public CompressionLevel As CompressionLevel
    'Public Encoding As String
    'Public Encryption As EncryptionAlgorithm
    'Public Folder As String
    Public File As String
    'Public Password As String
    'Public Zip64 As Zip64Option
    'Public ZipFlavor As Integer
    Public ZipName As String
End Class

Any advice would be great.


May 16, 2010 at 3:24 PM

I understand what you're saying.

You haven't provided a stacktrace, and I don't see an obvious place where the exception would occur.
So I can't provide any immediate assistance.

Do you understand the cross-threading issue?  if not, you might want to read this:


May 16, 2010 at 3:29 PM

Also, if you are zipping a single file, and if the file is not very large (let's say, under 10mb), you should be able to do the zipping on the UI thread,
with minimal UI freezing effects. The zip may take 1 second, which is a tolerable delay in a winforms app. 
You need additional threads and the handling for them, only if the zip save will take a long time.