Question SystemIOException

stulish

Well-known member
Joined
Jun 6, 2013
Messages
61
Programming Experience
3-5
Hi Guys,

I am getting an error on a program i created, the program seems to work great so i started trying to cause problems (as users will generally do), I have found i can get it to crash if i remove the removable USB drive while it is compressing data to it, below is a small program i created to generate an error i have been having within the larger program (if anyone wants to try it and see):

It just needs one Button and two labels on a form and System.IO.Compression and System.IO.Compression.FileSystem added as references.

VB.NET:
Imports System.Windows.Forms
Imports System
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.IO
Imports System.IO.Compression
Imports System.IO.DriveInfo
Imports System.Management
Imports System.Xml
Imports System.Threading
Public Class Form1
    Private WithEvents bw As BackgroundWorker = New BackgroundWorker
    Dim SaveLoc As String = "E:\"
    Dim startedCompress As Boolean = False
    Delegate Sub SetTextCallback([text] As String)
    Private demoThread As Thread = Nothing
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Try
            bw.RunWorkerAsync()

        Catch ex As Exception
            SetText2(DateTime.Now.ToString & " - Could not Compress files1: " & ex.Message)
            bw.CancelAsync()
            bw.Dispose()
        End Try
    End Sub
    Private Sub SetText1(ByVal [text] As String)

        ' InvokeRequired required compares the thread ID of the
        ' calling thread to the thread ID of the creating thread.
        ' If these threads are different, it returns true.
        If Label1.InvokeRequired Then
            Dim d As New SetTextCallback(AddressOf SetText1)
            Me.Invoke(d, New Object() {[text]})
        Else
            Label1.Text = [text]
        End If
    End Sub
    Private Sub SetText2(ByVal [text] As String)

        ' InvokeRequired required compares the thread ID of the
        ' calling thread to the thread ID of the creating thread.
        ' If these threads are different, it returns true.
        If Label2.InvokeRequired Then
            Dim d As New SetTextCallback(AddressOf SetText2)
            Me.Invoke(d, New Object() {[text]})
        Else
            Label2.Text = [text]
        End If
    End Sub

    Private Sub doCompress(ByVal fn As String)
        Try
            If Directory.Exists(Mid$(SaveLoc, 1, 3)) Then
                startedCompress = True
                If Not (fn.Contains("TestAudio")) And fn <> "" Then
                    Dim fileName As String = System.IO.Path.GetFileName(fn)
                    Dim dirname As String = DateTime.Now.ToString("yyyyMMdd-HHmmss")
                    If My.Computer.FileSystem.DirectoryExists(SaveLoc & "\" & dirname) = False Then
                        My.Computer.FileSystem.CreateDirectory(SaveLoc & "\" & dirname)
                    End If
                    Dim wavCompressname = "SND-" & fileName & ".zip"
                    Dim wavName = fileName & ".wav"
                    'Do Audio
                    If System.IO.File.Exists(SaveLoc & wavCompressname) Then
                        System.IO.File.Delete(SaveLoc & wavCompressname)
                    End If
                    Dim audDir As String = fn & "\"
                    Dim ZipDir As String = SaveLoc & dirname & "\" & wavCompressname
                    ' Debug.Print("-------------------------------------------------" & fileName & "--------------------------")
                    'Debug.Print(DateTime.Now.ToString & "    -    Start Compress")
                    If File.Exists(ZipDir) Then
                        ZipDir = ZipDir.Replace(".zip", "-1.zip")
                        '   Debug.Print("file exists - renameing file to: " & ZipDir)
                    End If
                    Try
                        ZipFile.CreateFromDirectory(audDir, ZipDir, CompressionLevel.Optimal, False)
                    Catch ex As Exception
                        SetText2(DateTime.Now.ToString & " - Zip Error")
                        bw.CancelAsync()
                        bw.Dispose()
                    End Try
                    startedCompress = False
                End If
            End If
        Catch dirNotFound As System.IO.DirectoryNotFoundException
            ' Code to handle DirectoryNotFoundException. 
            SetText2(DateTime.Now.ToString & " - Directory Not Found: ")
            bw.CancelAsync()
            bw.Dispose()
        Catch fileNotFound As System.IO.FileNotFoundException
            ' Code to handle FileNotFoundException. 
            SetText2(DateTime.Now.ToString & " - File Not Found: ")
            bw.CancelAsync()
            bw.Dispose()
        Catch *********** As System.IO.***********Exception
            ' Code to handle ***********Exception. 
            SetText2(DateTime.Now.ToString & " - Path Too Long: ")
            bw.CancelAsync()
            bw.Dispose()
        Catch ioEx As System.IO.IOException
            ' Code to handle IOException. 
            SetText2(DateTime.Now.ToString & " - IO: ")
            bw.CancelAsync()
            bw.Dispose()
        Catch security As System.Security.SecurityException
            ' Code to handle SecurityException. 
            SetText2(DateTime.Now.ToString & " - Security: ")
            bw.CancelAsync()
            bw.Dispose()
        Catch ex As Exception
            SetText2(DateTime.Now.ToString & " - Could not Compress files: " & ex.Message)
            bw.CancelAsync()
            bw.Dispose()
        End Try
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        bw.WorkerSupportsCancellation = True
        bw.WorkerReportsProgress = True

        AddHandler bw.DoWork, AddressOf bw_DoWork
        AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted
    End Sub

    Private Sub bw_DoWork(sender As Object, e As DoWorkEventArgs) Handles bw.DoWork
        SetText1(DateTime.Now.ToString & " - BW Started")
        Try
            If bw.CancellationPending = True Then
                e.Cancel = True
            Else
                'do work
                doCompress("C:\Temp\Test")
            End If
        Catch ex As Exception
            Debug.Print(DateTime.Now.ToString & " - Unable to start background worker thread: " & ex.Message)
            bw.CancelAsync()
            bw.Dispose()
        End Try
    End Sub

    Private Sub bw_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles bw.ProgressChanged
        SetText2("Prog Changed")
    End Sub

    Private Sub bw_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
        SetText1(DateTime.Now.ToString & " - BW Complete")
    End Sub
End Class
I put some stuff into the "C:\Temp\Test" directory, this will be zipped onto the flash drive located in the SaveLoc variable in this case "E:" when the button is clicked, make sure there is enough in the temp\test directory to take a little time to compress, i have about 23MB of images and audio this takes about 4-6 seconds to compress and save the files.

Once you click the button wait a second and then remove the USB flash drive (please use a clean drive as i would hate for anything you have on the drive becoming corrupt due to bad removal). I have had to do this 3 or 4 times before it shows the error below:

IOexception.jpg

The immediate window shows:

14/07/2016 16:07:57 - BW Started
14/07/2016 16:08:01 - BW Complete
14/07/2016 16:08:14 - BW Started
14/07/2016 16:08:18 - BW Complete
14/07/2016 16:08:24 - BW Started
14/07/2016 16:08:30 - BW Complete
14/07/2016 16:09:46 - BW Started
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
14/07/2016 16:09:47 - IO:
14/07/2016 16:09:47 - BW Complete
14/07/2016 16:10:03 - BW Started
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
14/07/2016 16:10:04 - IO:
14/07/2016 16:10:04 - BW Complete

A first chance exception of type 'System.IO.IOException' occurred in mscorlib.dll
The other error message i can get is still a IOException but the detail is: 'The volume for a file has been externally altered so that the opened file is no longer valid.'

I know people shouldn't remove USD brives while they are being written too, but i expect some users will and then moan that the app crashes.

I have checked the Exceptions settings in the IDE and nothing is checked:

system io exceptions.jpg

so i dont understand how sometimes it can be removed with no error and the try/catch working to catch the problem and other times it crashed the program.

Any ideas would be welcome.

Regards

Stu
 
Top Bottom