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:
Expand Collapse Copy
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
 
Back
Top