1

I have the following problem with SevenZipSharp. I want to compress a list(of String) containing filenames with full path. My code works fine, but only the last event(zip.CompressionFinished) is firing. Neither fFileCompressionStarted nor fCompressing is firing. What am I doing wrong?

Even if I set breakpoints in the event-subs or type "Stop", nothing happens.

Here is my code:

Dim working As Boolean
Private Sub start()
    Dim zip As New SevenZipCompressor
    zip.ArchiveFormat = OutArchiveFormat.SevenZip
    zip.CompressionMode = CompressionMode.Create
    zip.CompressionLevel = CompressionLevel.Fast
    zip.CompressionMethod = CompressionMethod.Lzma2
    zip.DirectoryStructure = True
    zip.FastCompression = True
    zip.IncludeEmptyDirectories = True
    zip.PreserveDirectoryRoot = True
    zip.TempFolderPath = System.IO.Path.GetTempPath()
    AddHandler zip.FileCompressionStarted, AddressOf fFileCompressionStarted
    AddHandler zip.Compressing, AddressOf fCompressing
    AddHandler zip.CompressionFinished, AddressOf Compress_Finished
    working = True
    Label10.Text = "Startup..."
    Application.DoEvents()

    zip.BeginCompressFiles(filename, flist.ToArray)
    While working = True
        Threading.Thread.Sleep(250)
        Application.DoEvents()
    End While
End Sub

Private Sub fFileCompressionStarted(ByVal sender As Object, ByVal e As SevenZip.FileNameEventArgs)
    Debug.Print(("Compressing " + e.FileName + e.PercentDone.ToString))
    Label10.Text = e.FileName
    MsVistaProgressBar1.Value = e.PercentDone
    Application.DoEvents()
End Sub
Private Sub fCompressing(sender As Object, e As SevenZip.ProgressEventArgs)
    MsVistaProgressBar1.Value = e.PercentDone
    Application.DoEvents()
End Sub
Private Sub Compress_Finished(sender As Object, e As EventArgs)
    MsVistaProgressBar1.Value = 0
    Label10.Text = "Ready."
    working = False
    Application.DoEvents()
End Sub
muffi
  • 366
  • 6
  • 18
  • 1
    All those `DoEvents` calls are just asking for trouble. Why are they there? If you're trying to keep the UI responsive, then that's an indication that you should be doing your work in the background. You should investigate using a `BackgroundWorker`. It may help you diagnose your event issue as well. – Chris Dunaway Sep 18 '17 at 13:21
  • Unfortunately, your comment is no solution. My first thought was, to do DoEvents in order to force the complete UI to update. But later I found out, that the events are not firing, I will of course delete them later. – muffi Sep 18 '17 at 13:25
  • Chris is right, using `Application.DoEvents()` to keep your UI responsive is _**bad practice!**_ I've explained a little about that in my answer about multithreading, here: https://stackoverflow.com/a/45571728/3740093 – Visual Vincent Sep 18 '17 at 13:28
  • `My first thought was, to do DoEvents in order to force the complete UI to update` - `DoEvents()` doesn't force the UI to update ([**`Form.Refresh()`**](https://msdn.microsoft.com/en-us/library/system.windows.forms.control.refresh(v=vs.110).aspx) does however). `Application.DoEvents()` merely processes all _**currently available**_ window messages, which is already done automatically by the built-in message loop. The `DoEvents()` calls simply doesn't do anything extra that isn't already taken care of by the framework. – Visual Vincent Sep 18 '17 at 13:31
  • Away from that, is there any solution for my problem? – muffi Sep 19 '17 at 04:27
  • BTW, for testing purpose, I changed all DoEvents to Me.Refresh(). Now, no events are firing, it hangs for eternity, even if compression is completed (this event fires using DoEvents() !!!). – muffi Sep 19 '17 at 05:19
  • Remove the loops alltogether! I don't see what they could possibly be good for?? -- `Refresh()` _redraws_ the form, while `DoEvents()` handles window messages (I never said changing to the former would solve your problem, I merely corrected your statement). The reason your events (or some of them) get raised is because `DoEvents()` processes _**all**_ currently available information on the UI (which still is **very bad**, since that should **ONLY** be done by the framework - **_NOT_ by you!**) – Visual Vincent Sep 20 '17 at 17:31
  • Please read this for further information on why _**not to use**_ `DoEvents()`: [**Keeping your UI Responsive and the Dangers of Application.DoEvents**](https://blogs.msdn.microsoft.com/jfoscoding/2005/08/06/keeping-your-ui-responsive-and-the-dangers-of-application-doevents/) – Visual Vincent Sep 20 '17 at 17:36
  • As for your actual issue, if you really want to wait for the `start()` method rather than to just respond to the `CompressionFinished` event you should look into some solution combining [**reset events and async/await**](https://stackoverflow.com/a/18766131/3740093). -- But for simple debugging purposes, what happens if you just ignore the need to wait and just respond to the `CompressionFinished` event? – Visual Vincent Sep 20 '17 at 17:41
  • 1
    Vincent, I know the article of microsoft about DoEvents(). But for testing and debugging, it is still fast to code and good enough. At release, you are right. But in the mean time, I changed the archiver to DotNetZip and my Sub runs fine now. – muffi Sep 21 '17 at 04:28

1 Answers1

2

Sorry to dig up this old question, but I was struggling with the same issue yesterday. I found that setting FastCompression to False will cause the events to fire properly.

davefatkin
  • 21
  • 2
  • Nice, I used in the meantime ZIP, it is working properly. my main goal was 7z and I will try your solution. Thanks! – muffi Apr 06 '18 at 04:31