IO errors with "folder watcher" program

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Keith G Hicks

    IO errors with "folder watcher" program

    I'm having a lot of trouble with "file in use" errors in my "folder watcher"
    project. Starting and stopping the watcher and reading my XML file work
    fine. Once the watcher is started, I'm reading the text files from the
    watched folder line by line into variables and then posting them to a SQL
    table.

    All of the code for the form is shown below. And it works fine except for 2
    issues.

    First issue: In the Finally of the Try for teh SQL code I have this:

    sqlComm.Connect ion.Close()
    sqlComm.Dispose ()
    sqlConn.Dispose ()

    I get this type of intellisense warning: "Variable sqlComm is used before it
    has been assigned a value. A null reference exception could result at
    runtime." What do I need to rearange to avoid this problem? Sometimes it
    causes crash and sometimes not. If the file cannot be opened for some
    reason, don't I want to free the sqlComm variable if the code fails?

    Second issue (and this is the big problem really): IO errors. I run the
    program and then copy and paste 4 text files into the watched folder. They
    all get processed exactly as I expect. Everything below appears to run just
    fine. Then, without restartign the watcher program, I copy 4 different files
    into the watched folder. This time only 2 of them are processed. The other 2
    generate the error below:

    "The process cannot access the file 'D:\FilesToImpo rt\217068F01.tx t' because
    it is being used by another process."

    Well it's not in use by anything I'm doing manually. I get this error pretty
    consistently when I do what I described above. Sometimes 2 files don't work
    and sometimes only 1. Sometimes they both process fine but that's very rare.
    Usually at least one of them fails. I have no idea why. It doesn't depend on
    the particular file either. It's always the first batch (whether it's 1 file
    or 30) processes fine after I start up the watcher exe. Then when I drop any
    number of additional files into the watched folder 1 or more of them
    generate the error above.

    I sure hope someone can point out the problems so I can get this running.
    I'm pretty frustrated with it right now.

    Thanks,

    Keith


    Here's all the code for this form:


    Imports System
    Imports System.Xml
    Imports System.IO
    Imports System.Diagnost ics
    Imports System.Data.Sql Client
    Imports System.Text.Reg ularExpressions

    Public Class NoticeImport

    Private watchFolder As FileSystemWatch er
    Private dataSource As String, _
    dataBase As String, _
    userName As String, _
    password As String, _
    monitoredCustom er As String, _
    textFilesLocati on As String, _
    fntName As String, _
    fntSize As Double, _
    clipWidth As String

    Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
    System.EventArg s) Handles MyBase.Load
    btnStartWatchin g.Enabled = True
    btnStopWatching .Enabled = False
    Me.Text = "Monitoring for Customer: None"
    txtWatchFolder. Text = "Watching Folder: None "
    End Sub

    Private Sub btnStartWatchin g_Click(ByVal sender As System.Object, ByVal
    e As System.EventArg s) Handles btnStartWatchin g.Click

    watchFolder = New System.IO.FileS ystemWatcher()

    'Get the db login info and the location of the input text files from
    the xml file

    Dim sAppPathAndName As String = Application.Exe cutablePath
    Dim sAppPathOnly As String = Mid(sAppPathAnd Name, 1,
    InStr(sAppPathA ndName, "FNTNoticeImpor t.exe", CompareMethod.T ext) - 1)

    textFilesLocati on = ""

    Try

    Dim xrdr As New XmlTextReader(s AppPathOnly &
    "FNTNoticeImpor tSettings.xml")
    xrdr.Whitespace Handling = WhitespaceHandl ing.None

    While xrdr.Read()

    If String.Compare( xrdr.Name, "dataSource ", True) = 0 Then
    dataSource = xrdr.ReadElemen tString()
    End If

    If String.Compare( xrdr.Name, "dataBase", True) = 0 Then
    dataBase = xrdr.ReadElemen tString()
    End If

    If String.Compare( xrdr.Name, "userName", True) = 0 Then
    userName = xrdr.ReadElemen tString()
    End If

    If String.Compare( xrdr.Name, "password", True) = 0 Then
    password = xrdr.ReadElemen tString()
    End If

    If String.Compare( xrdr.Name, "monitoredCusto mer", True) = 0
    Then
    monitoredCustom er = xrdr.ReadElemen tString()
    End If

    If String.Compare( xrdr.Name, "textFilesLocat ion", True) = 0
    Then
    textFilesLocati on = xrdr.ReadElemen tString()
    End If

    If String.Compare( xrdr.Name, "fntName", True) = 0 Then
    fntName = xrdr.ReadElemen tString()
    End If

    If String.Compare( xrdr.Name, "fntSize", True) = 0 Then
    fntSize = xrdr.ReadElemen tString()
    End If

    If String.Compare( xrdr.Name, "clipWidth" , True) = 0 Then
    clipWidth = xrdr.ReadElemen tString() 'clip width is in
    hundredths of an inch
    End If

    End While

    xrdr.Close()

    'tell the watcher where to watch
    watchFolder.Pat h = textFilesLocati on
    Me.Text = "Monitoring for Customer: " & monitoredCustom er
    txtWatchFolder. Text = "Watching Folder: " & textFilesLocati on

    'add a list of Filter we want to specify
    'make sure you use OR for each Filter as we need to all of those

    watchFolder.Not ifyFilter = IO.NotifyFilter s.DirectoryName
    watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
    IO.NotifyFilter s.FileName
    watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
    IO.NotifyFilter s.Attributes


    ' add the handler to each event
    AddHandler watchFolder.Cha nged, AddressOf logChange
    AddHandler watchFolder.Cre ated, AddressOf logChange
    AddHandler watchFolder.Del eted, AddressOf logChange

    ' add the rename handler as the signature is different
    AddHandler watchFolder.Ren amed, AddressOf logrename

    'Set this property to true to start watching
    watchFolder.Ena bleRaisingEvent s = True
    watchFolder.Inc ludeSubdirector ies = False
    watchFolder.Fil ter = "*.txt"

    btnStartWatchin g.Enabled = False
    btnStopWatching .Enabled = True

    Catch ex As XmlException
    MsgBox("XML Error " & ex.Message & " occurred. Cannot start
    watching process.")
    Exit Sub

    Catch ex As Exception
    MsgBox("Error " & ex.Message & " occurred. Cannot start watching
    process.")
    Exit Sub

    End Try

    End Sub

    Private Sub logChange(ByVal source As Object, ByVal e As
    System.IO.FileS ystemEventArgs)

    'Don't use this for now
    'If e.ChangeType = IO.WatcherChang eTypes.Changed Then
    ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
    modified" & vbCrLf
    'End If

    If e.ChangeType = IO.WatcherChang eTypes.Created Then
    'txtFolderActiv ity.Text &= e.Name & " received at " & Now() &
    vbCrLf
    If InStr(e.Name, ".txt", CompareMethod.T ext) Then
    Call ImportTextFiles (e.Name)
    'Debug.Print(e. Name)
    End If
    End If

    'Don't use this for now
    'If e.ChangeType = IO.WatcherChang eTypes.Deleted Then
    ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
    deleted" & vbCrLf
    'End If

    End Sub

    Public Sub logrename(ByVal source As Object, ByVal e As
    System.IO.Renam edEventArgs)
    'Don't use this for now
    'txtFolderActiv ity.Text &= "File" & e.OldName & " has been renamed
    to " & e.Name & vbCrLf
    End Sub

    Private Sub btnStopWatching _Click(ByVal sender As System.Object, ByVal e
    As System.EventArg s) Handles btnStopWatching .Click
    ' Stop watching the folder
    watchFolder.Ena bleRaisingEvent s = False
    btnStartWatchin g.Enabled = True
    btnStopWatching .Enabled = False
    Me.Text = "Monitoring for Customer: None"
    txtWatchFolder. Text = "Watching Folder: None "
    End Sub

    Private Sub ImportTextFiles (ByVal sFileToImport As String)

    'Process the file

    Dim dfc As New DlnpFntCalcs.Dl npFntCalcs
    Dim srLine As String
    Dim iFileLineCount As Integer, _
    iNoticeTextLine Count As Integer
    Dim bInNoticeText As Boolean
    Dim AdTypeCode As String, _
    ImportType As String, _
    AttorneyFileNum As String, _
    AttyOfficeName As String, _
    MortgagorFirstN ame As String, _
    MortgagorLastNa me As String, _
    PropAddress1 As String, _
    PropAddress2 As String, _
    PropCity As String, _
    PropState As String, _
    PropZip As String, _
    FirstPubDate As String, _
    NumWeeksToRun As String, _
    LastPubDate As String, _
    County As String, _
    DateOfSale As String, _
    FullNoticeText As String, _
    NoticeTextHeigh t As Double, _
    WholeImportFile As String

    ImportType = ""
    AttorneyFileNum = ""
    AttyOfficeName = ""
    MortgagorFirstN ame = ""
    MortgagorLastNa me = ""
    PropAddress1 = ""
    PropAddress2 = ""
    PropCity = ""
    PropState = ""
    PropZip = ""
    FirstPubDate = ""
    NumWeeksToRun = ""
    LastPubDate = ""
    County = ""
    DateOfSale = ""
    FullNoticeText = ""
    WholeImportFile = ""

    bInNoticeText = False
    iFileLineCount = 0
    iNoticeTextLine Count = 0

    Dim sr As StreamReader

    'Open the text file
    Try
    sr = New StreamReader(te xtFilesLocation & sFileToImport)
    Catch ex As Exception
    txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
    while trying to open file " & sFileToImport & ". File NOT imported (" &
    Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
    Exit Sub
    End Try

    'Read the text file line by line
    Try
    Do
    srLine = sr.ReadLine()

    iFileLineCount += 1
    If iFileLineCount = 1 Then
    WholeImportFile = srLine
    Else
    WholeImportFile = WholeImportFile & vbCrLf & srLine
    End If

    'TODO 2008-08-13 - AdTypeCode will need to come from import
    file at some point
    AdTypeCode = "M"
    'If InStr(srLine, "Ad Tpe:", CompareMethod.T ext) Then
    ' AdTypeCode = Trim(Mid(srLine , 8))
    'End If

    If InStr(srLine, "Publicatio n Notice:", CompareMethod.T ext)
    Then
    ImportType = Trim(Mid(srLine , 20))
    End If

    If InStr(srLine, "File Number:", CompareMethod.T ext) Then
    AttorneyFileNum = Trim(Mid(srLine , 13))
    End If

    'TODO 2008-08-13 - AttorneyName will need to come from
    import file at some point when we use this for other attorneys
    If InStr(srLine, "Team:", CompareMethod.T ext) Then
    AttyOfficeName = Trim(Mid(srLine , 6))
    AttyOfficeName = "Trott & Trott P.C. (team " &
    AttyOfficeName & ")"
    End If

    If InStr(srLine, "Mortgagor First:", CompareMethod.T ext)
    Then
    MortgagorFirstN ame = Trim(Mid(srLine , 17))
    End If

    If InStr(srLine, "Mortgagor Last:", CompareMethod.T ext) Then
    MortgagorLastNa me = Trim(Mid(srLine , 16))
    End If

    If InStr(srLine, "Property Address 1:", CompareMethod.T ext)
    Then
    PropAddress1 = Trim(Mid(srLine , 20))
    End If

    If InStr(srLine, "Property Address 2:", CompareMethod.T ext)
    Then
    PropAddress2 = Trim(Mid(srLine , 20))
    End If

    If InStr(srLine, "City:", CompareMethod.T ext) Then
    PropCity = Trim(Mid(srLine , 6))
    End If

    If InStr(srLine, "State:", CompareMethod.T ext) Then
    PropState = Trim(Mid(srLine , 7))
    End If

    If InStr(srLine, "ZIP:", CompareMethod.T ext) Then
    PropZip = Trim(Mid(srLine , 5))
    End If

    If InStr(srLine, "First Publication Date:",
    CompareMethod.T ext) Then
    FirstPubDate = Trim(Mid(srLine , 24))
    End If

    If InStr(srLine, "Number Of Insertions:",
    CompareMethod.T ext) Then
    NumWeeksToRun = Trim(Mid(srLine , 22))
    End If

    If InStr(srLine, "Last Pub Date:", CompareMethod.T ext) Then
    LastPubDate = Trim(Mid(srLine , 15))
    End If

    If InStr(srLine, "County:", CompareMethod.T ext) Then
    County = Trim(Mid(srLine , 8))
    End If

    If InStr(srLine, "Sale Date:", CompareMethod.T ext) Then
    DateOfSale = Trim(Mid(srLine , 11))
    End If

    'TODO 2008-08-07 - only do the following if it's new or
    correction (not if cancel)
    If InStr(srLine, "*** Begin Notice ***", CompareMethod.T ext)
    0 Then
    'skip 1 line and read the rest into the FullNoticeText
    variable
    srLine = sr.ReadLine()
    iNoticeTextLine Count = 1 'we're on line one now and will
    get it into FullNoticeText below
    WholeImportFile = WholeImportFile & vbCrLf & srLine
    'have to do this here because we're skipping a line. if we don't then the
    similar line above won't catch the skipped line
    bInNoticeText = True
    End If

    If bInNoticeText Then
    If InStr(srLine, "*** End Notice ***",
    CompareMethod.T ext) = 0 Then
    If iNoticeTextLine Count = 1 Then
    FullNoticeText = srLine
    Else
    FullNoticeText = FullNoticeText & vbCrLf &
    srLine
    End If
    iNoticeTextLine Count += 1
    End If
    End If

    Loop Until InStr(srLine, "*** End Notice ***",
    CompareMethod.T ext) <0


    'If this is a correction, then there is info AFTER the "*** End
    Notice ***" line that we need to read into the WholeImportFile variable
    If String.Compare( ImportType, "Correct", True) = 0 Then
    WholeImportFile = WholeImportFile & vbCrLf & sr.ReadToEnd()
    End If

    Catch ex As Exception
    txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
    while trying to read file " & sFileToImport & ". File NOT imported (" &
    Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
    Exit Sub
    Finally
    'do not need sr after all the above reading is done
    sr.Close()
    sr.Dispose()
    End Try


    'get the height in decimal inches (rounded to 2 places)
    Try
    If FullNoticeText <"" Then
    NoticeTextHeigh t = (dfc.NoticeText Height(FullNoti ceText,
    fntName, fntSize, clipWidth))
    Else
    NoticeTextHeigh t = 0
    End If
    Catch ex As Exception
    txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
    while calling dll to get text height on file " & sFileToImport & ". File NOT
    imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
    Exit Sub
    End Try


    Dim sqlConn As SqlConnection
    Dim sqlComm As SqlCommand

    'get the data into the database
    Try

    sqlConn = New SqlConnection(" Data Source=" & dataSource &
    ";Initial Catalog=" & dataBase & ";User Id=" & userName & ";Password= " &
    password & ";")
    sqlConn.Open()

    sqlComm = New SqlCommand("sp_ ImportNotices", sqlConn)
    sqlComm.Command Type = CommandType.Sto redProcedure

    sqlComm.Paramet ers.Add("RETURN _VALUE", SqlDbType.Int). Value = 0
    sqlComm.Paramet ers("RETURN_VAL UE").Directio n =
    ParameterDirect ion.ReturnValue
    sqlComm.Paramet ers.Add("@AdTyp eCode", SqlDbType.VarCh ar,
    50).Value = IIf(AdTypeCode = "", DBNull.Value, AdTypeCode)
    sqlComm.Paramet ers.Add("@Impor tType", SqlDbType.VarCh ar,
    50).Value = IIf(ImportType = "", DBNull.Value, ImportType)
    sqlComm.Paramet ers.Add("@Attor neyFileNum", SqlDbType.VarCh ar,
    50).Value = IIf(AttorneyFil eNum = "", DBNull.Value, AttorneyFileNum )
    sqlComm.Paramet ers.Add("@AttyO fficeName", SqlDbType.VarCh ar,
    200).Value = IIf(AttyOfficeN ame = "", DBNull.Value, AttyOfficeName)
    sqlComm.Paramet ers.Add("@Mortg agorFirstName", SqlDbType.VarCh ar,
    50).Value = IIf(MortgagorFi rstName = "", DBNull.Value, MortgagorFirstN ame)
    sqlComm.Paramet ers.Add("@Mortg agorLastName", SqlDbType.VarCh ar,
    50).Value = IIf(MortgagorLa stName = "", DBNull.Value, MortgagorLastNa me)
    sqlComm.Paramet ers.Add("@PropA ddress1", SqlDbType.VarCh ar,
    100).Value = IIf(PropAddress 1 = "", DBNull.Value, PropAddress1)
    sqlComm.Paramet ers.Add("@PropA ddress2", SqlDbType.VarCh ar,
    100).Value = IIf(PropAddress 2 = "", DBNull.Value, PropAddress2)
    sqlComm.Paramet ers.Add("@PropC ity", SqlDbType.VarCh ar,
    100).Value = IIf(PropCity = "", DBNull.Value, PropCity)
    sqlComm.Paramet ers.Add("@PropS tate", SqlDbType.VarCh ar,
    50).Value = IIf(PropState = "", DBNull.Value, PropState)
    sqlComm.Paramet ers.Add("@PropZ ip", SqlDbType.VarCh ar, 20).Value
    = IIf(PropZip = "", DBNull.Value, PropZip)
    sqlComm.Paramet ers.Add("@First PubDate", SqlDbType.VarCh ar,
    50).Value = IIf(FirstPubDat e = "", DBNull.Value, FirstPubDate)
    sqlComm.Paramet ers.Add("@NumWe eksToRun", SqlDbType.VarCh ar,
    10).Value = IIf(NumWeeksToR un = "", DBNull.Value, NumWeeksToRun)
    sqlComm.Paramet ers.Add("@LastP ubDate", SqlDbType.VarCh ar,
    50).Value = IIf(LastPubDate = "", DBNull.Value, LastPubDate)
    sqlComm.Paramet ers.Add("@Count y", SqlDbType.VarCh ar, 50).Value =
    IIf(County = "", DBNull.Value, County)
    sqlComm.Paramet ers.Add("@DateO fSale", SqlDbType.VarCh ar,
    50).Value = IIf(DateOfSale = "", DBNull.Value, DateOfSale)
    sqlComm.Paramet ers.Add("@FullN oticeText", SqlDbType.Text) .Value
    = IIf(FullNoticeT ext = "", DBNull.Value, FullNoticeText)
    sqlComm.Paramet ers.Add("@Notic eTextHeight", SqlDbType.Decim al,
    5).Value = CDbl(NoticeText Height)
    sqlComm.Paramet ers.Add("@Whole ImportFile", SqlDbType.Text) .Value
    = IIf(WholeImport File = "", DBNull.Value, WholeImportFile )
    sqlComm.Paramet ers.Add("@TextF ileName", SqlDbType.VarCh ar,
    500).Value = sFileToImport
    sqlComm.Paramet ers.Add("@Reaso nsNotPosted", SqlDbType.VarCh ar,
    500).Value = DBNull.Value
    sqlComm.Paramet ers("@ReasonsNo tPosted").Direc tion =
    ParameterDirect ion.Output

    sqlComm.Execute NonQuery()

    If sqlComm.Paramet ers("RETURN_VAL UE").Value <0 Then
    txtFolderActivi ty.Text &= "SQL Error " &
    sqlComm.Paramet ers("RETURN_VAL UE").Value.ToSt ring & " on file " &
    sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") &
    ")." & vbCrLf
    Exit Sub
    End If

    Catch ex As SqlException
    txtFolderActivi ty.Text &= "SQL Error " & ex.Message & " occurred
    while executing SQL procedure sp_ImportNotice s on file " & sFileToImport &
    ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
    Exit Sub
    Catch ex As Exception
    txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
    while executing SQL procedure sp_ImportNotice s on file " & sFileToImport &
    ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
    Exit Sub
    Finally

    sqlComm.Connect ion.Close()
    sqlComm.Dispose ()
    sqlConn.Dispose ()
    End Try

    'if the "ImportedNotice Files" folder does not yet exist, create it
    Try
    If Not Directory.Exist s(textFilesLoca tion &
    "ImportedNotice Files") Then
    Directory.Creat eDirectory(text FilesLocation &
    "ImportedNotice Files")
    'don't go on until the folder has been created
    Do Until Directory.Exist s(textFilesLoca tion &
    "ImportedNotice Files")
    System.Threadin g.Thread.Sleep( 500)
    Loop
    End If
    Catch ex As IOException
    txtFolderActivi ty.Text &= "IO Error " & ex.Message & "
    attempting to create ImportedNoticeF iles folder while importing file " &
    sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") &
    ")." & vbCrLf
    End Try

    'store the finished file in the ImportedNoticeF iles folder for
    someone to manually review (delete it first if for some reason it already
    exists)
    Try
    If File.Exists(tex tFilesLocation & "ImportedNotice Files\" &
    sFileToImport) Then
    File.Delete(tex tFilesLocation & "ImportedNotice Files\" &
    sFileToImport)
    'Need to wait for the file to be deleted before moving on.
    Do Until Not File.Exists(tex tFilesLocation &
    "ImportedNotice Files\" & sFileToImport)
    System.Threadin g.Thread.Sleep( 500)
    Loop
    End If
    Catch ex As IOException
    txtFolderActivi ty.Text &= "File " & sFileToImport & " was
    imported but IO Error " & ex.Message & " occurred while attempting to delete
    the previously imported file with the same name (" & Format(Now(), "m/d/yy
    hh:mm:ss") & ")." & vbCrLf
    Exit Sub
    End Try

    Try
    File.Move(textF ilesLocation & sFileToImport, textFilesLocati on &
    "ImportedNotice Files\" & sFileToImport)
    Catch ex As IOException
    txtFolderActivi ty.Text &= "IO Error " & ex.Message & " occurred
    while attempting to move file " & sFileToImport & " to the
    ImportedNoticeF iles folder. File NOT imported (" & Format(Now(), "m/d/yy
    hh:mm:ss") & ")." & vbCrLf
    Exit Sub
    End Try

    txtFolderActivi ty.Text &= "File " & sFileToImport & " has been
    imported successfully and has been moved to the ImportedNoticeF iles
    subfolder (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf

    End Sub

    End Class


  • Phill W.

    #2
    Re: IO errors with &quot;folder watcher&quot; program

    Keith G Hicks wrote:
    I'm having a lot of trouble with "file in use" errors in my "folder watcher"
    project. Starting and stopping the watcher and reading my XML file work
    fine.
    Second issue (and this is the big problem really): IO errors. I run the
    program and then copy and paste 4 text files into the watched folder. They
    all get processed exactly as I expect. Everything below appears to run just
    fine. Then, without restartign the watcher program, I copy 4 different files
    into the watched folder. This time only 2 of them are processed. The other 2
    generate the error below:
    Is it possible that the FileSystemWatch er is "jumping on" the /same/
    file twice in rapid succession?

    I've noticed that the FileSystemWatch er has a nasty habit of raising
    multiple events when you might only expect one and doing so in a very
    short space of time. I suspect the FileSystemWatch er has its own
    Thread, so straight away you're into the nastiness of cross-threading
    and race conditions.

    Try putting a SyncLock inside the method that reads the file content and
    see if that helps any, as in:

    Private Sub ImportTextFiles (ByVal sFileToImport As String)
    Dim lockObject as New Object ' always a Private variable

    SyncLock lockObject

    'Process the file

    Dim dfc As New DlnpFntCalcs.Dl npFntCalcs
    . . .

    End SyncLock

    HTH,
    Phill W.

    Comment

    • Keith G Hicks

      #3
      Re: IO errors with &quot;folder watcher&quot; program

      Thanks for the suggestion Phil but SyncLock didn't do it. And you could be
      right. I read that FileSystemWatch er can raising multiple events somewhere.
      It could be using a single file more than once very quickly. What confuses
      me is that it *never* does that the first time around. It always works just
      fine. It's onlly after that when there's a problem.



      "Phill W." <p-.-a-.-w-a-r-d-@-o-p-e-n-.-a-c-.-u-kwrote in message
      news:g93crb$gl5 $1@south.jnrs.j a.net...
      Keith G Hicks wrote:
      >
      I'm having a lot of trouble with "file in use" errors in my "folder
      watcher"
      project. Starting and stopping the watcher and reading my XML file work
      fine.
      >
      Second issue (and this is the big problem really): IO errors. I run the
      program and then copy and paste 4 text files into the watched folder.
      They
      all get processed exactly as I expect. Everything below appears to run
      just
      fine. Then, without restartign the watcher program, I copy 4 different
      files
      into the watched folder. This time only 2 of them are processed. The
      other 2
      generate the error below:
      >
      Is it possible that the FileSystemWatch er is "jumping on" the /same/
      file twice in rapid succession?
      >
      I've noticed that the FileSystemWatch er has a nasty habit of raising
      multiple events when you might only expect one and doing so in a very
      short space of time. I suspect the FileSystemWatch er has its own
      Thread, so straight away you're into the nastiness of cross-threading
      and race conditions.
      >
      Try putting a SyncLock inside the method that reads the file content and
      see if that helps any, as in:
      >
      Private Sub ImportTextFiles (ByVal sFileToImport As String)
      Dim lockObject as New Object ' always a Private variable
      >
      SyncLock lockObject
      >
      'Process the file
      >
      Dim dfc As New DlnpFntCalcs.Dl npFntCalcs
      . . .
      >
      End SyncLock
      >
      HTH,
      Phill W.

      Comment

      • Wolfgang Hauer

        #4
        Re: IO errors with &quot;folder watcher&quot; program

        Any Antivirus prog is running?


        Wolfgang

        "Keith G Hicks" <krh@comcast.ne tschrieb im Newsbeitrag
        news:e1FZ4E7BJH A.4368@TK2MSFTN GP06.phx.gbl...
        I'm having a lot of trouble with "file in use" errors in my "folder
        watcher"
        project. Starting and stopping the watcher and reading my XML file work
        fine. Once the watcher is started, I'm reading the text files from the
        watched folder line by line into variables and then posting them to a SQL
        table.
        >
        All of the code for the form is shown below. And it works fine except for
        2
        issues.
        >
        First issue: In the Finally of the Try for teh SQL code I have this:
        >
        sqlComm.Connect ion.Close()
        sqlComm.Dispose ()
        sqlConn.Dispose ()
        >
        I get this type of intellisense warning: "Variable sqlComm is used before
        it
        has been assigned a value. A null reference exception could result at
        runtime." What do I need to rearange to avoid this problem? Sometimes it
        causes crash and sometimes not. If the file cannot be opened for some
        reason, don't I want to free the sqlComm variable if the code fails?
        >
        Second issue (and this is the big problem really): IO errors. I run the
        program and then copy and paste 4 text files into the watched folder. They
        all get processed exactly as I expect. Everything below appears to run
        just
        fine. Then, without restartign the watcher program, I copy 4 different
        files
        into the watched folder. This time only 2 of them are processed. The other
        2
        generate the error below:
        >
        "The process cannot access the file 'D:\FilesToImpo rt\217068F01.tx t'
        because
        it is being used by another process."
        >
        Well it's not in use by anything I'm doing manually. I get this error
        pretty
        consistently when I do what I described above. Sometimes 2 files don't
        work
        and sometimes only 1. Sometimes they both process fine but that's very
        rare.
        Usually at least one of them fails. I have no idea why. It doesn't depend
        on
        the particular file either. It's always the first batch (whether it's 1
        file
        or 30) processes fine after I start up the watcher exe. Then when I drop
        any
        number of additional files into the watched folder 1 or more of them
        generate the error above.
        >
        I sure hope someone can point out the problems so I can get this running.
        I'm pretty frustrated with it right now.
        >
        Thanks,
        >
        Keith
        >
        >
        Here's all the code for this form:
        >
        >
        Imports System
        Imports System.Xml
        Imports System.IO
        Imports System.Diagnost ics
        Imports System.Data.Sql Client
        Imports System.Text.Reg ularExpressions
        >
        Public Class NoticeImport
        >
        Private watchFolder As FileSystemWatch er
        Private dataSource As String, _
        dataBase As String, _
        userName As String, _
        password As String, _
        monitoredCustom er As String, _
        textFilesLocati on As String, _
        fntName As String, _
        fntSize As Double, _
        clipWidth As String
        >
        Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
        System.EventArg s) Handles MyBase.Load
        btnStartWatchin g.Enabled = True
        btnStopWatching .Enabled = False
        Me.Text = "Monitoring for Customer: None"
        txtWatchFolder. Text = "Watching Folder: None "
        End Sub
        >
        Private Sub btnStartWatchin g_Click(ByVal sender As System.Object, ByVal
        e As System.EventArg s) Handles btnStartWatchin g.Click
        >
        watchFolder = New System.IO.FileS ystemWatcher()
        >
        'Get the db login info and the location of the input text files
        from
        the xml file
        >
        Dim sAppPathAndName As String = Application.Exe cutablePath
        Dim sAppPathOnly As String = Mid(sAppPathAnd Name, 1,
        InStr(sAppPathA ndName, "FNTNoticeImpor t.exe", CompareMethod.T ext) - 1)
        >
        textFilesLocati on = ""
        >
        Try
        >
        Dim xrdr As New XmlTextReader(s AppPathOnly &
        "FNTNoticeImpor tSettings.xml")
        xrdr.Whitespace Handling = WhitespaceHandl ing.None
        >
        While xrdr.Read()
        >
        If String.Compare( xrdr.Name, "dataSource ", True) = 0 Then
        dataSource = xrdr.ReadElemen tString()
        End If
        >
        If String.Compare( xrdr.Name, "dataBase", True) = 0 Then
        dataBase = xrdr.ReadElemen tString()
        End If
        >
        If String.Compare( xrdr.Name, "userName", True) = 0 Then
        userName = xrdr.ReadElemen tString()
        End If
        >
        If String.Compare( xrdr.Name, "password", True) = 0 Then
        password = xrdr.ReadElemen tString()
        End If
        >
        If String.Compare( xrdr.Name, "monitoredCusto mer", True) = 0
        Then
        monitoredCustom er = xrdr.ReadElemen tString()
        End If
        >
        If String.Compare( xrdr.Name, "textFilesLocat ion", True) = 0
        Then
        textFilesLocati on = xrdr.ReadElemen tString()
        End If
        >
        If String.Compare( xrdr.Name, "fntName", True) = 0 Then
        fntName = xrdr.ReadElemen tString()
        End If
        >
        If String.Compare( xrdr.Name, "fntSize", True) = 0 Then
        fntSize = xrdr.ReadElemen tString()
        End If
        >
        If String.Compare( xrdr.Name, "clipWidth" , True) = 0 Then
        clipWidth = xrdr.ReadElemen tString() 'clip width is in
        hundredths of an inch
        End If
        >
        End While
        >
        xrdr.Close()
        >
        'tell the watcher where to watch
        watchFolder.Pat h = textFilesLocati on
        Me.Text = "Monitoring for Customer: " & monitoredCustom er
        txtWatchFolder. Text = "Watching Folder: " & textFilesLocati on
        >
        'add a list of Filter we want to specify
        'make sure you use OR for each Filter as we need to all of
        those
        >
        watchFolder.Not ifyFilter = IO.NotifyFilter s.DirectoryName
        watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
        IO.NotifyFilter s.FileName
        watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
        IO.NotifyFilter s.Attributes
        >
        >
        ' add the handler to each event
        AddHandler watchFolder.Cha nged, AddressOf logChange
        AddHandler watchFolder.Cre ated, AddressOf logChange
        AddHandler watchFolder.Del eted, AddressOf logChange
        >
        ' add the rename handler as the signature is different
        AddHandler watchFolder.Ren amed, AddressOf logrename
        >
        'Set this property to true to start watching
        watchFolder.Ena bleRaisingEvent s = True
        watchFolder.Inc ludeSubdirector ies = False
        watchFolder.Fil ter = "*.txt"
        >
        btnStartWatchin g.Enabled = False
        btnStopWatching .Enabled = True
        >
        Catch ex As XmlException
        MsgBox("XML Error " & ex.Message & " occurred. Cannot start
        watching process.")
        Exit Sub
        >
        Catch ex As Exception
        MsgBox("Error " & ex.Message & " occurred. Cannot start
        watching
        process.")
        Exit Sub
        >
        End Try
        >
        End Sub
        >
        Private Sub logChange(ByVal source As Object, ByVal e As
        System.IO.FileS ystemEventArgs)
        >
        'Don't use this for now
        'If e.ChangeType = IO.WatcherChang eTypes.Changed Then
        ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
        modified" & vbCrLf
        'End If
        >
        If e.ChangeType = IO.WatcherChang eTypes.Created Then
        'txtFolderActiv ity.Text &= e.Name & " received at " & Now() &
        vbCrLf
        If InStr(e.Name, ".txt", CompareMethod.T ext) Then
        Call ImportTextFiles (e.Name)
        'Debug.Print(e. Name)
        End If
        End If
        >
        'Don't use this for now
        'If e.ChangeType = IO.WatcherChang eTypes.Deleted Then
        ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
        deleted" & vbCrLf
        'End If
        >
        End Sub
        >
        Public Sub logrename(ByVal source As Object, ByVal e As
        System.IO.Renam edEventArgs)
        'Don't use this for now
        'txtFolderActiv ity.Text &= "File" & e.OldName & " has been renamed
        to " & e.Name & vbCrLf
        End Sub
        >
        Private Sub btnStopWatching _Click(ByVal sender As System.Object, ByVal
        e
        As System.EventArg s) Handles btnStopWatching .Click
        ' Stop watching the folder
        watchFolder.Ena bleRaisingEvent s = False
        btnStartWatchin g.Enabled = True
        btnStopWatching .Enabled = False
        Me.Text = "Monitoring for Customer: None"
        txtWatchFolder. Text = "Watching Folder: None "
        End Sub
        >
        Private Sub ImportTextFiles (ByVal sFileToImport As String)
        >
        'Process the file
        >
        Dim dfc As New DlnpFntCalcs.Dl npFntCalcs
        Dim srLine As String
        Dim iFileLineCount As Integer, _
        iNoticeTextLine Count As Integer
        Dim bInNoticeText As Boolean
        Dim AdTypeCode As String, _
        ImportType As String, _
        AttorneyFileNum As String, _
        AttyOfficeName As String, _
        MortgagorFirstN ame As String, _
        MortgagorLastNa me As String, _
        PropAddress1 As String, _
        PropAddress2 As String, _
        PropCity As String, _
        PropState As String, _
        PropZip As String, _
        FirstPubDate As String, _
        NumWeeksToRun As String, _
        LastPubDate As String, _
        County As String, _
        DateOfSale As String, _
        FullNoticeText As String, _
        NoticeTextHeigh t As Double, _
        WholeImportFile As String
        >
        ImportType = ""
        AttorneyFileNum = ""
        AttyOfficeName = ""
        MortgagorFirstN ame = ""
        MortgagorLastNa me = ""
        PropAddress1 = ""
        PropAddress2 = ""
        PropCity = ""
        PropState = ""
        PropZip = ""
        FirstPubDate = ""
        NumWeeksToRun = ""
        LastPubDate = ""
        County = ""
        DateOfSale = ""
        FullNoticeText = ""
        WholeImportFile = ""
        >
        bInNoticeText = False
        iFileLineCount = 0
        iNoticeTextLine Count = 0
        >
        Dim sr As StreamReader
        >
        'Open the text file
        Try
        sr = New StreamReader(te xtFilesLocation & sFileToImport)
        Catch ex As Exception
        txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
        while trying to open file " & sFileToImport & ". File NOT imported (" &
        Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
        Exit Sub
        End Try
        >
        'Read the text file line by line
        Try
        Do
        srLine = sr.ReadLine()
        >
        iFileLineCount += 1
        If iFileLineCount = 1 Then
        WholeImportFile = srLine
        Else
        WholeImportFile = WholeImportFile & vbCrLf & srLine
        End If
        >
        'TODO 2008-08-13 - AdTypeCode will need to come from import
        file at some point
        AdTypeCode = "M"
        'If InStr(srLine, "Ad Tpe:", CompareMethod.T ext) Then
        ' AdTypeCode = Trim(Mid(srLine , 8))
        'End If
        >
        If InStr(srLine, "Publicatio n Notice:", CompareMethod.T ext)
        Then
        ImportType = Trim(Mid(srLine , 20))
        End If
        >
        If InStr(srLine, "File Number:", CompareMethod.T ext) Then
        AttorneyFileNum = Trim(Mid(srLine , 13))
        End If
        >
        'TODO 2008-08-13 - AttorneyName will need to come from
        import file at some point when we use this for other attorneys
        If InStr(srLine, "Team:", CompareMethod.T ext) Then
        AttyOfficeName = Trim(Mid(srLine , 6))
        AttyOfficeName = "Trott & Trott P.C. (team " &
        AttyOfficeName & ")"
        End If
        >
        If InStr(srLine, "Mortgagor First:", CompareMethod.T ext)
        Then
        MortgagorFirstN ame = Trim(Mid(srLine , 17))
        End If
        >
        If InStr(srLine, "Mortgagor Last:", CompareMethod.T ext)
        Then
        MortgagorLastNa me = Trim(Mid(srLine , 16))
        End If
        >
        If InStr(srLine, "Property Address 1:", CompareMethod.T ext)
        Then
        PropAddress1 = Trim(Mid(srLine , 20))
        End If
        >
        If InStr(srLine, "Property Address 2:", CompareMethod.T ext)
        Then
        PropAddress2 = Trim(Mid(srLine , 20))
        End If
        >
        If InStr(srLine, "City:", CompareMethod.T ext) Then
        PropCity = Trim(Mid(srLine , 6))
        End If
        >
        If InStr(srLine, "State:", CompareMethod.T ext) Then
        PropState = Trim(Mid(srLine , 7))
        End If
        >
        If InStr(srLine, "ZIP:", CompareMethod.T ext) Then
        PropZip = Trim(Mid(srLine , 5))
        End If
        >
        If InStr(srLine, "First Publication Date:",
        CompareMethod.T ext) Then
        FirstPubDate = Trim(Mid(srLine , 24))
        End If
        >
        If InStr(srLine, "Number Of Insertions:",
        CompareMethod.T ext) Then
        NumWeeksToRun = Trim(Mid(srLine , 22))
        End If
        >
        If InStr(srLine, "Last Pub Date:", CompareMethod.T ext) Then
        LastPubDate = Trim(Mid(srLine , 15))
        End If
        >
        If InStr(srLine, "County:", CompareMethod.T ext) Then
        County = Trim(Mid(srLine , 8))
        End If
        >
        If InStr(srLine, "Sale Date:", CompareMethod.T ext) Then
        DateOfSale = Trim(Mid(srLine , 11))
        End If
        >
        'TODO 2008-08-07 - only do the following if it's new or
        correction (not if cancel)
        If InStr(srLine, "*** Begin Notice ***",
        CompareMethod.T ext)
        >0 Then
        'skip 1 line and read the rest into the FullNoticeText
        variable
        srLine = sr.ReadLine()
        iNoticeTextLine Count = 1 'we're on line one now and
        will
        get it into FullNoticeText below
        WholeImportFile = WholeImportFile & vbCrLf & srLine
        'have to do this here because we're skipping a line. if we don't then the
        similar line above won't catch the skipped line
        bInNoticeText = True
        End If
        >
        If bInNoticeText Then
        If InStr(srLine, "*** End Notice ***",
        CompareMethod.T ext) = 0 Then
        If iNoticeTextLine Count = 1 Then
        FullNoticeText = srLine
        Else
        FullNoticeText = FullNoticeText & vbCrLf &
        srLine
        End If
        iNoticeTextLine Count += 1
        End If
        End If
        >
        Loop Until InStr(srLine, "*** End Notice ***",
        CompareMethod.T ext) <0
        >
        >
        'If this is a correction, then there is info AFTER the "*** End
        Notice ***" line that we need to read into the WholeImportFile variable
        If String.Compare( ImportType, "Correct", True) = 0 Then
        WholeImportFile = WholeImportFile & vbCrLf & sr.ReadToEnd()
        End If
        >
        Catch ex As Exception
        txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
        while trying to read file " & sFileToImport & ". File NOT imported (" &
        Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
        Exit Sub
        Finally
        'do not need sr after all the above reading is done
        sr.Close()
        sr.Dispose()
        End Try
        >
        >
        'get the height in decimal inches (rounded to 2 places)
        Try
        If FullNoticeText <"" Then
        NoticeTextHeigh t = (dfc.NoticeText Height(FullNoti ceText,
        fntName, fntSize, clipWidth))
        Else
        NoticeTextHeigh t = 0
        End If
        Catch ex As Exception
        txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
        while calling dll to get text height on file " & sFileToImport & ". File
        NOT
        imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
        Exit Sub
        End Try
        >
        >
        Dim sqlConn As SqlConnection
        Dim sqlComm As SqlCommand
        >
        'get the data into the database
        Try
        >
        sqlConn = New SqlConnection(" Data Source=" & dataSource &
        ";Initial Catalog=" & dataBase & ";User Id=" & userName & ";Password= " &
        password & ";")
        sqlConn.Open()
        >
        sqlComm = New SqlCommand("sp_ ImportNotices", sqlConn)
        sqlComm.Command Type = CommandType.Sto redProcedure
        >
        sqlComm.Paramet ers.Add("RETURN _VALUE", SqlDbType.Int). Value = 0
        sqlComm.Paramet ers("RETURN_VAL UE").Directio n =
        ParameterDirect ion.ReturnValue
        sqlComm.Paramet ers.Add("@AdTyp eCode", SqlDbType.VarCh ar,
        50).Value = IIf(AdTypeCode = "", DBNull.Value, AdTypeCode)
        sqlComm.Paramet ers.Add("@Impor tType", SqlDbType.VarCh ar,
        50).Value = IIf(ImportType = "", DBNull.Value, ImportType)
        sqlComm.Paramet ers.Add("@Attor neyFileNum", SqlDbType.VarCh ar,
        50).Value = IIf(AttorneyFil eNum = "", DBNull.Value, AttorneyFileNum )
        sqlComm.Paramet ers.Add("@AttyO fficeName", SqlDbType.VarCh ar,
        200).Value = IIf(AttyOfficeN ame = "", DBNull.Value, AttyOfficeName)
        sqlComm.Paramet ers.Add("@Mortg agorFirstName",
        SqlDbType.VarCh ar,
        50).Value = IIf(MortgagorFi rstName = "", DBNull.Value, MortgagorFirstN ame)
        sqlComm.Paramet ers.Add("@Mortg agorLastName", SqlDbType.VarCh ar,
        50).Value = IIf(MortgagorLa stName = "", DBNull.Value, MortgagorLastNa me)
        sqlComm.Paramet ers.Add("@PropA ddress1", SqlDbType.VarCh ar,
        100).Value = IIf(PropAddress 1 = "", DBNull.Value, PropAddress1)
        sqlComm.Paramet ers.Add("@PropA ddress2", SqlDbType.VarCh ar,
        100).Value = IIf(PropAddress 2 = "", DBNull.Value, PropAddress2)
        sqlComm.Paramet ers.Add("@PropC ity", SqlDbType.VarCh ar,
        100).Value = IIf(PropCity = "", DBNull.Value, PropCity)
        sqlComm.Paramet ers.Add("@PropS tate", SqlDbType.VarCh ar,
        50).Value = IIf(PropState = "", DBNull.Value, PropState)
        sqlComm.Paramet ers.Add("@PropZ ip", SqlDbType.VarCh ar, 20).Value
        = IIf(PropZip = "", DBNull.Value, PropZip)
        sqlComm.Paramet ers.Add("@First PubDate", SqlDbType.VarCh ar,
        50).Value = IIf(FirstPubDat e = "", DBNull.Value, FirstPubDate)
        sqlComm.Paramet ers.Add("@NumWe eksToRun", SqlDbType.VarCh ar,
        10).Value = IIf(NumWeeksToR un = "", DBNull.Value, NumWeeksToRun)
        sqlComm.Paramet ers.Add("@LastP ubDate", SqlDbType.VarCh ar,
        50).Value = IIf(LastPubDate = "", DBNull.Value, LastPubDate)
        sqlComm.Paramet ers.Add("@Count y", SqlDbType.VarCh ar, 50).Value
        =
        IIf(County = "", DBNull.Value, County)
        sqlComm.Paramet ers.Add("@DateO fSale", SqlDbType.VarCh ar,
        50).Value = IIf(DateOfSale = "", DBNull.Value, DateOfSale)
        sqlComm.Paramet ers.Add("@FullN oticeText", SqlDbType.Text) .Value
        = IIf(FullNoticeT ext = "", DBNull.Value, FullNoticeText)
        sqlComm.Paramet ers.Add("@Notic eTextHeight", SqlDbType.Decim al,
        5).Value = CDbl(NoticeText Height)
        sqlComm.Paramet ers.Add("@Whole ImportFile",
        SqlDbType.Text) .Value
        = IIf(WholeImport File = "", DBNull.Value, WholeImportFile )
        sqlComm.Paramet ers.Add("@TextF ileName", SqlDbType.VarCh ar,
        500).Value = sFileToImport
        sqlComm.Paramet ers.Add("@Reaso nsNotPosted", SqlDbType.VarCh ar,
        500).Value = DBNull.Value
        sqlComm.Paramet ers("@ReasonsNo tPosted").Direc tion =
        ParameterDirect ion.Output
        >
        sqlComm.Execute NonQuery()
        >
        If sqlComm.Paramet ers("RETURN_VAL UE").Value <0 Then
        txtFolderActivi ty.Text &= "SQL Error " &
        sqlComm.Paramet ers("RETURN_VAL UE").Value.ToSt ring & " on file " &
        sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss")
        &
        ")." & vbCrLf
        Exit Sub
        End If
        >
        Catch ex As SqlException
        txtFolderActivi ty.Text &= "SQL Error " & ex.Message & "
        occurred
        while executing SQL procedure sp_ImportNotice s on file " & sFileToImport &
        ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
        Exit Sub
        Catch ex As Exception
        txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
        while executing SQL procedure sp_ImportNotice s on file " & sFileToImport &
        ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
        Exit Sub
        Finally
        >
        sqlComm.Connect ion.Close()
        sqlComm.Dispose ()
        sqlConn.Dispose ()
        End Try
        >
        'if the "ImportedNotice Files" folder does not yet exist, create it
        Try
        If Not Directory.Exist s(textFilesLoca tion &
        "ImportedNotice Files") Then
        Directory.Creat eDirectory(text FilesLocation &
        "ImportedNotice Files")
        'don't go on until the folder has been created
        Do Until Directory.Exist s(textFilesLoca tion &
        "ImportedNotice Files")
        System.Threadin g.Thread.Sleep( 500)
        Loop
        End If
        Catch ex As IOException
        txtFolderActivi ty.Text &= "IO Error " & ex.Message & "
        attempting to create ImportedNoticeF iles folder while importing file " &
        sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss")
        &
        ")." & vbCrLf
        End Try
        >
        'store the finished file in the ImportedNoticeF iles folder for
        someone to manually review (delete it first if for some reason it already
        exists)
        Try
        If File.Exists(tex tFilesLocation & "ImportedNotice Files\" &
        sFileToImport) Then
        File.Delete(tex tFilesLocation & "ImportedNotice Files\" &
        sFileToImport)
        'Need to wait for the file to be deleted before moving on.
        Do Until Not File.Exists(tex tFilesLocation &
        "ImportedNotice Files\" & sFileToImport)
        System.Threadin g.Thread.Sleep( 500)
        Loop
        End If
        Catch ex As IOException
        txtFolderActivi ty.Text &= "File " & sFileToImport & " was
        imported but IO Error " & ex.Message & " occurred while attempting to
        delete
        the previously imported file with the same name (" & Format(Now(), "m/d/yy
        hh:mm:ss") & ")." & vbCrLf
        Exit Sub
        End Try
        >
        Try
        File.Move(textF ilesLocation & sFileToImport, textFilesLocati on
        &
        "ImportedNotice Files\" & sFileToImport)
        Catch ex As IOException
        txtFolderActivi ty.Text &= "IO Error " & ex.Message & " occurred
        while attempting to move file " & sFileToImport & " to the
        ImportedNoticeF iles folder. File NOT imported (" & Format(Now(), "m/d/yy
        hh:mm:ss") & ")." & vbCrLf
        Exit Sub
        End Try
        >
        txtFolderActivi ty.Text &= "File " & sFileToImport & " has been
        imported successfully and has been moved to the ImportedNoticeF iles
        subfolder (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
        >
        End Sub
        >
        End Class
        >
        >

        Comment

        • Keith G Hicks

          #5
          Re: IO errors with &quot;folder watcher&quot; program

          Yes. AVG. And Zone Alarm firewall.


          "Wolfgang Hauer" <hauer@DELETETH ATsysdat.atwrot e in message
          news:OdCfCjGCJH A.3496@TK2MSFTN GP03.phx.gbl...
          Any Antivirus prog is running?
          >
          >
          Wolfgang
          >
          "Keith G Hicks" <krh@comcast.ne tschrieb im Newsbeitrag
          news:e1FZ4E7BJH A.4368@TK2MSFTN GP06.phx.gbl...
          I'm having a lot of trouble with "file in use" errors in my "folder
          watcher"
          project. Starting and stopping the watcher and reading my XML file work
          fine. Once the watcher is started, I'm reading the text files from the
          watched folder line by line into variables and then posting them to a
          SQL
          table.

          All of the code for the form is shown below. And it works fine except
          for
          2
          issues.

          First issue: In the Finally of the Try for teh SQL code I have this:

          sqlComm.Connect ion.Close()
          sqlComm.Dispose ()
          sqlConn.Dispose ()

          I get this type of intellisense warning: "Variable sqlComm is used
          before
          it
          has been assigned a value. A null reference exception could result at
          runtime." What do I need to rearange to avoid this problem? Sometimes it
          causes crash and sometimes not. If the file cannot be opened for some
          reason, don't I want to free the sqlComm variable if the code fails?

          Second issue (and this is the big problem really): IO errors. I run the
          program and then copy and paste 4 text files into the watched folder.
          They
          all get processed exactly as I expect. Everything below appears to run
          just
          fine. Then, without restartign the watcher program, I copy 4 different
          files
          into the watched folder. This time only 2 of them are processed. The
          other
          2
          generate the error below:

          "The process cannot access the file 'D:\FilesToImpo rt\217068F01.tx t'
          because
          it is being used by another process."

          Well it's not in use by anything I'm doing manually. I get this error
          pretty
          consistently when I do what I described above. Sometimes 2 files don't
          work
          and sometimes only 1. Sometimes they both process fine but that's very
          rare.
          Usually at least one of them fails. I have no idea why. It doesn't
          depend
          on
          the particular file either. It's always the first batch (whether it's 1
          file
          or 30) processes fine after I start up the watcher exe. Then when I drop
          any
          number of additional files into the watched folder 1 or more of them
          generate the error above.

          I sure hope someone can point out the problems so I can get this
          running.
          I'm pretty frustrated with it right now.

          Thanks,

          Keith


          Here's all the code for this form:


          Imports System
          Imports System.Xml
          Imports System.IO
          Imports System.Diagnost ics
          Imports System.Data.Sql Client
          Imports System.Text.Reg ularExpressions

          Public Class NoticeImport

          Private watchFolder As FileSystemWatch er
          Private dataSource As String, _
          dataBase As String, _
          userName As String, _
          password As String, _
          monitoredCustom er As String, _
          textFilesLocati on As String, _
          fntName As String, _
          fntSize As Double, _
          clipWidth As String

          Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
          System.EventArg s) Handles MyBase.Load
          btnStartWatchin g.Enabled = True
          btnStopWatching .Enabled = False
          Me.Text = "Monitoring for Customer: None"
          txtWatchFolder. Text = "Watching Folder: None "
          End Sub

          Private Sub btnStartWatchin g_Click(ByVal sender As System.Object,
          ByVal
          e As System.EventArg s) Handles btnStartWatchin g.Click

          watchFolder = New System.IO.FileS ystemWatcher()

          'Get the db login info and the location of the input text files
          from
          the xml file

          Dim sAppPathAndName As String = Application.Exe cutablePath
          Dim sAppPathOnly As String = Mid(sAppPathAnd Name, 1,
          InStr(sAppPathA ndName, "FNTNoticeImpor t.exe", CompareMethod.T ext) - 1)

          textFilesLocati on = ""

          Try

          Dim xrdr As New XmlTextReader(s AppPathOnly &
          "FNTNoticeImpor tSettings.xml")
          xrdr.Whitespace Handling = WhitespaceHandl ing.None

          While xrdr.Read()

          If String.Compare( xrdr.Name, "dataSource ", True) = 0 Then
          dataSource = xrdr.ReadElemen tString()
          End If

          If String.Compare( xrdr.Name, "dataBase", True) = 0 Then
          dataBase = xrdr.ReadElemen tString()
          End If

          If String.Compare( xrdr.Name, "userName", True) = 0 Then
          userName = xrdr.ReadElemen tString()
          End If

          If String.Compare( xrdr.Name, "password", True) = 0 Then
          password = xrdr.ReadElemen tString()
          End If

          If String.Compare( xrdr.Name, "monitoredCusto mer", True) =
          0
          Then
          monitoredCustom er = xrdr.ReadElemen tString()
          End If

          If String.Compare( xrdr.Name, "textFilesLocat ion", True) =
          0
          Then
          textFilesLocati on = xrdr.ReadElemen tString()
          End If

          If String.Compare( xrdr.Name, "fntName", True) = 0 Then
          fntName = xrdr.ReadElemen tString()
          End If

          If String.Compare( xrdr.Name, "fntSize", True) = 0 Then
          fntSize = xrdr.ReadElemen tString()
          End If

          If String.Compare( xrdr.Name, "clipWidth" , True) = 0 Then
          clipWidth = xrdr.ReadElemen tString() 'clip width is
          in
          hundredths of an inch
          End If

          End While

          xrdr.Close()

          'tell the watcher where to watch
          watchFolder.Pat h = textFilesLocati on
          Me.Text = "Monitoring for Customer: " & monitoredCustom er
          txtWatchFolder. Text = "Watching Folder: " & textFilesLocati on

          'add a list of Filter we want to specify
          'make sure you use OR for each Filter as we need to all of
          those

          watchFolder.Not ifyFilter = IO.NotifyFilter s.DirectoryName
          watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
          IO.NotifyFilter s.FileName
          watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
          IO.NotifyFilter s.Attributes


          ' add the handler to each event
          AddHandler watchFolder.Cha nged, AddressOf logChange
          AddHandler watchFolder.Cre ated, AddressOf logChange
          AddHandler watchFolder.Del eted, AddressOf logChange

          ' add the rename handler as the signature is different
          AddHandler watchFolder.Ren amed, AddressOf logrename

          'Set this property to true to start watching
          watchFolder.Ena bleRaisingEvent s = True
          watchFolder.Inc ludeSubdirector ies = False
          watchFolder.Fil ter = "*.txt"

          btnStartWatchin g.Enabled = False
          btnStopWatching .Enabled = True

          Catch ex As XmlException
          MsgBox("XML Error " & ex.Message & " occurred. Cannot start
          watching process.")
          Exit Sub

          Catch ex As Exception
          MsgBox("Error " & ex.Message & " occurred. Cannot start
          watching
          process.")
          Exit Sub

          End Try

          End Sub

          Private Sub logChange(ByVal source As Object, ByVal e As
          System.IO.FileS ystemEventArgs)

          'Don't use this for now
          'If e.ChangeType = IO.WatcherChang eTypes.Changed Then
          ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
          modified" & vbCrLf
          'End If

          If e.ChangeType = IO.WatcherChang eTypes.Created Then
          'txtFolderActiv ity.Text &= e.Name & " received at " & Now() &
          vbCrLf
          If InStr(e.Name, ".txt", CompareMethod.T ext) Then
          Call ImportTextFiles (e.Name)
          'Debug.Print(e. Name)
          End If
          End If

          'Don't use this for now
          'If e.ChangeType = IO.WatcherChang eTypes.Deleted Then
          ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
          deleted" & vbCrLf
          'End If

          End Sub

          Public Sub logrename(ByVal source As Object, ByVal e As
          System.IO.Renam edEventArgs)
          'Don't use this for now
          'txtFolderActiv ity.Text &= "File" & e.OldName & " has been
          renamed
          to " & e.Name & vbCrLf
          End Sub

          Private Sub btnStopWatching _Click(ByVal sender As System.Object,
          ByVal
          e
          As System.EventArg s) Handles btnStopWatching .Click
          ' Stop watching the folder
          watchFolder.Ena bleRaisingEvent s = False
          btnStartWatchin g.Enabled = True
          btnStopWatching .Enabled = False
          Me.Text = "Monitoring for Customer: None"
          txtWatchFolder. Text = "Watching Folder: None "
          End Sub

          Private Sub ImportTextFiles (ByVal sFileToImport As String)

          'Process the file

          Dim dfc As New DlnpFntCalcs.Dl npFntCalcs
          Dim srLine As String
          Dim iFileLineCount As Integer, _
          iNoticeTextLine Count As Integer
          Dim bInNoticeText As Boolean
          Dim AdTypeCode As String, _
          ImportType As String, _
          AttorneyFileNum As String, _
          AttyOfficeName As String, _
          MortgagorFirstN ame As String, _
          MortgagorLastNa me As String, _
          PropAddress1 As String, _
          PropAddress2 As String, _
          PropCity As String, _
          PropState As String, _
          PropZip As String, _
          FirstPubDate As String, _
          NumWeeksToRun As String, _
          LastPubDate As String, _
          County As String, _
          DateOfSale As String, _
          FullNoticeText As String, _
          NoticeTextHeigh t As Double, _
          WholeImportFile As String

          ImportType = ""
          AttorneyFileNum = ""
          AttyOfficeName = ""
          MortgagorFirstN ame = ""
          MortgagorLastNa me = ""
          PropAddress1 = ""
          PropAddress2 = ""
          PropCity = ""
          PropState = ""
          PropZip = ""
          FirstPubDate = ""
          NumWeeksToRun = ""
          LastPubDate = ""
          County = ""
          DateOfSale = ""
          FullNoticeText = ""
          WholeImportFile = ""

          bInNoticeText = False
          iFileLineCount = 0
          iNoticeTextLine Count = 0

          Dim sr As StreamReader

          'Open the text file
          Try
          sr = New StreamReader(te xtFilesLocation & sFileToImport)
          Catch ex As Exception
          txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
          while trying to open file " & sFileToImport & ". File NOT imported (" &
          Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
          Exit Sub
          End Try

          'Read the text file line by line
          Try
          Do
          srLine = sr.ReadLine()

          iFileLineCount += 1
          If iFileLineCount = 1 Then
          WholeImportFile = srLine
          Else
          WholeImportFile = WholeImportFile & vbCrLf & srLine
          End If

          'TODO 2008-08-13 - AdTypeCode will need to come from
          import
          file at some point
          AdTypeCode = "M"
          'If InStr(srLine, "Ad Tpe:", CompareMethod.T ext) Then
          ' AdTypeCode = Trim(Mid(srLine , 8))
          'End If

          If InStr(srLine, "Publicatio n Notice:",
          CompareMethod.T ext)
          Then
          ImportType = Trim(Mid(srLine , 20))
          End If

          If InStr(srLine, "File Number:", CompareMethod.T ext) Then
          AttorneyFileNum = Trim(Mid(srLine , 13))
          End If

          'TODO 2008-08-13 - AttorneyName will need to come from
          import file at some point when we use this for other attorneys
          If InStr(srLine, "Team:", CompareMethod.T ext) Then
          AttyOfficeName = Trim(Mid(srLine , 6))
          AttyOfficeName = "Trott & Trott P.C. (team " &
          AttyOfficeName & ")"
          End If

          If InStr(srLine, "Mortgagor First:", CompareMethod.T ext)
          Then
          MortgagorFirstN ame = Trim(Mid(srLine , 17))
          End If

          If InStr(srLine, "Mortgagor Last:", CompareMethod.T ext)
          Then
          MortgagorLastNa me = Trim(Mid(srLine , 16))
          End If

          If InStr(srLine, "Property Address 1:",
          CompareMethod.T ext)
          Then
          PropAddress1 = Trim(Mid(srLine , 20))
          End If

          If InStr(srLine, "Property Address 2:",
          CompareMethod.T ext)
          Then
          PropAddress2 = Trim(Mid(srLine , 20))
          End If

          If InStr(srLine, "City:", CompareMethod.T ext) Then
          PropCity = Trim(Mid(srLine , 6))
          End If

          If InStr(srLine, "State:", CompareMethod.T ext) Then
          PropState = Trim(Mid(srLine , 7))
          End If

          If InStr(srLine, "ZIP:", CompareMethod.T ext) Then
          PropZip = Trim(Mid(srLine , 5))
          End If

          If InStr(srLine, "First Publication Date:",
          CompareMethod.T ext) Then
          FirstPubDate = Trim(Mid(srLine , 24))
          End If

          If InStr(srLine, "Number Of Insertions:",
          CompareMethod.T ext) Then
          NumWeeksToRun = Trim(Mid(srLine , 22))
          End If

          If InStr(srLine, "Last Pub Date:", CompareMethod.T ext)
          Then
          LastPubDate = Trim(Mid(srLine , 15))
          End If

          If InStr(srLine, "County:", CompareMethod.T ext) Then
          County = Trim(Mid(srLine , 8))
          End If

          If InStr(srLine, "Sale Date:", CompareMethod.T ext) Then
          DateOfSale = Trim(Mid(srLine , 11))
          End If

          'TODO 2008-08-07 - only do the following if it's new or
          correction (not if cancel)
          If InStr(srLine, "*** Begin Notice ***",
          CompareMethod.T ext)
          0 Then
          'skip 1 line and read the rest into the
          FullNoticeText
          variable
          srLine = sr.ReadLine()
          iNoticeTextLine Count = 1 'we're on line one now and
          will
          get it into FullNoticeText below
          WholeImportFile = WholeImportFile & vbCrLf & srLine
          'have to do this here because we're skipping a line. if we don't then
          the
          similar line above won't catch the skipped line
          bInNoticeText = True
          End If

          If bInNoticeText Then
          If InStr(srLine, "*** End Notice ***",
          CompareMethod.T ext) = 0 Then
          If iNoticeTextLine Count = 1 Then
          FullNoticeText = srLine
          Else
          FullNoticeText = FullNoticeText & vbCrLf &
          srLine
          End If
          iNoticeTextLine Count += 1
          End If
          End If

          Loop Until InStr(srLine, "*** End Notice ***",
          CompareMethod.T ext) <0


          'If this is a correction, then there is info AFTER the "***
          End
          Notice ***" line that we need to read into the WholeImportFile variable
          If String.Compare( ImportType, "Correct", True) = 0 Then
          WholeImportFile = WholeImportFile & vbCrLf &
          sr.ReadToEnd()
          End If

          Catch ex As Exception
          txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
          while trying to read file " & sFileToImport & ". File NOT imported (" &
          Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
          Exit Sub
          Finally
          'do not need sr after all the above reading is done
          sr.Close()
          sr.Dispose()
          End Try


          'get the height in decimal inches (rounded to 2 places)
          Try
          If FullNoticeText <"" Then
          NoticeTextHeigh t = (dfc.NoticeText Height(FullNoti ceText,
          fntName, fntSize, clipWidth))
          Else
          NoticeTextHeigh t = 0
          End If
          Catch ex As Exception
          txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
          while calling dll to get text height on file " & sFileToImport & ". File
          NOT
          imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
          Exit Sub
          End Try


          Dim sqlConn As SqlConnection
          Dim sqlComm As SqlCommand

          'get the data into the database
          Try

          sqlConn = New SqlConnection(" Data Source=" & dataSource &
          ";Initial Catalog=" & dataBase & ";User Id=" & userName & ";Password= " &
          password & ";")
          sqlConn.Open()

          sqlComm = New SqlCommand("sp_ ImportNotices", sqlConn)
          sqlComm.Command Type = CommandType.Sto redProcedure

          sqlComm.Paramet ers.Add("RETURN _VALUE", SqlDbType.Int). Value =
          0
          sqlComm.Paramet ers("RETURN_VAL UE").Directio n =
          ParameterDirect ion.ReturnValue
          sqlComm.Paramet ers.Add("@AdTyp eCode", SqlDbType.VarCh ar,
          50).Value = IIf(AdTypeCode = "", DBNull.Value, AdTypeCode)
          sqlComm.Paramet ers.Add("@Impor tType", SqlDbType.VarCh ar,
          50).Value = IIf(ImportType = "", DBNull.Value, ImportType)
          sqlComm.Paramet ers.Add("@Attor neyFileNum", SqlDbType.VarCh ar,
          50).Value = IIf(AttorneyFil eNum = "", DBNull.Value, AttorneyFileNum )
          sqlComm.Paramet ers.Add("@AttyO fficeName", SqlDbType.VarCh ar,
          200).Value = IIf(AttyOfficeN ame = "", DBNull.Value, AttyOfficeName)
          sqlComm.Paramet ers.Add("@Mortg agorFirstName",
          SqlDbType.VarCh ar,
          50).Value = IIf(MortgagorFi rstName = "", DBNull.Value,
          MortgagorFirstN ame)
          sqlComm.Paramet ers.Add("@Mortg agorLastName",
          SqlDbType.VarCh ar,
          50).Value = IIf(MortgagorLa stName = "", DBNull.Value, MortgagorLastNa me)
          sqlComm.Paramet ers.Add("@PropA ddress1", SqlDbType.VarCh ar,
          100).Value = IIf(PropAddress 1 = "", DBNull.Value, PropAddress1)
          sqlComm.Paramet ers.Add("@PropA ddress2", SqlDbType.VarCh ar,
          100).Value = IIf(PropAddress 2 = "", DBNull.Value, PropAddress2)
          sqlComm.Paramet ers.Add("@PropC ity", SqlDbType.VarCh ar,
          100).Value = IIf(PropCity = "", DBNull.Value, PropCity)
          sqlComm.Paramet ers.Add("@PropS tate", SqlDbType.VarCh ar,
          50).Value = IIf(PropState = "", DBNull.Value, PropState)
          sqlComm.Paramet ers.Add("@PropZ ip", SqlDbType.VarCh ar,
          20).Value
          = IIf(PropZip = "", DBNull.Value, PropZip)
          sqlComm.Paramet ers.Add("@First PubDate", SqlDbType.VarCh ar,
          50).Value = IIf(FirstPubDat e = "", DBNull.Value, FirstPubDate)
          sqlComm.Paramet ers.Add("@NumWe eksToRun", SqlDbType.VarCh ar,
          10).Value = IIf(NumWeeksToR un = "", DBNull.Value, NumWeeksToRun)
          sqlComm.Paramet ers.Add("@LastP ubDate", SqlDbType.VarCh ar,
          50).Value = IIf(LastPubDate = "", DBNull.Value, LastPubDate)
          sqlComm.Paramet ers.Add("@Count y", SqlDbType.VarCh ar,
          50).Value
          =
          IIf(County = "", DBNull.Value, County)
          sqlComm.Paramet ers.Add("@DateO fSale", SqlDbType.VarCh ar,
          50).Value = IIf(DateOfSale = "", DBNull.Value, DateOfSale)
          sqlComm.Paramet ers.Add("@FullN oticeText",
          SqlDbType.Text) .Value
          = IIf(FullNoticeT ext = "", DBNull.Value, FullNoticeText)
          sqlComm.Paramet ers.Add("@Notic eTextHeight",
          SqlDbType.Decim al,
          5).Value = CDbl(NoticeText Height)
          sqlComm.Paramet ers.Add("@Whole ImportFile",
          SqlDbType.Text) .Value
          = IIf(WholeImport File = "", DBNull.Value, WholeImportFile )
          sqlComm.Paramet ers.Add("@TextF ileName", SqlDbType.VarCh ar,
          500).Value = sFileToImport
          sqlComm.Paramet ers.Add("@Reaso nsNotPosted",
          SqlDbType.VarCh ar,
          500).Value = DBNull.Value
          sqlComm.Paramet ers("@ReasonsNo tPosted").Direc tion =
          ParameterDirect ion.Output

          sqlComm.Execute NonQuery()

          If sqlComm.Paramet ers("RETURN_VAL UE").Value <0 Then
          txtFolderActivi ty.Text &= "SQL Error " &
          sqlComm.Paramet ers("RETURN_VAL UE").Value.ToSt ring & " on file " &
          sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy
          hh:mm:ss")
          &
          ")." & vbCrLf
          Exit Sub
          End If

          Catch ex As SqlException
          txtFolderActivi ty.Text &= "SQL Error " & ex.Message & "
          occurred
          while executing SQL procedure sp_ImportNotice s on file " & sFileToImport
          &
          ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." &
          vbCrLf
          Exit Sub
          Catch ex As Exception
          txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
          while executing SQL procedure sp_ImportNotice s on file " & sFileToImport
          &
          ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." &
          vbCrLf
          Exit Sub
          Finally

          sqlComm.Connect ion.Close()
          sqlComm.Dispose ()
          sqlConn.Dispose ()
          End Try

          'if the "ImportedNotice Files" folder does not yet exist, create
          it
          Try
          If Not Directory.Exist s(textFilesLoca tion &
          "ImportedNotice Files") Then
          Directory.Creat eDirectory(text FilesLocation &
          "ImportedNotice Files")
          'don't go on until the folder has been created
          Do Until Directory.Exist s(textFilesLoca tion &
          "ImportedNotice Files")
          System.Threadin g.Thread.Sleep( 500)
          Loop
          End If
          Catch ex As IOException
          txtFolderActivi ty.Text &= "IO Error " & ex.Message & "
          attempting to create ImportedNoticeF iles folder while importing file " &
          sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy
          hh:mm:ss")
          &
          ")." & vbCrLf
          End Try

          'store the finished file in the ImportedNoticeF iles folder for
          someone to manually review (delete it first if for some reason it
          already
          exists)
          Try
          If File.Exists(tex tFilesLocation & "ImportedNotice Files\" &
          sFileToImport) Then
          File.Delete(tex tFilesLocation & "ImportedNotice Files\" &
          sFileToImport)
          'Need to wait for the file to be deleted before moving
          on.
          Do Until Not File.Exists(tex tFilesLocation &
          "ImportedNotice Files\" & sFileToImport)
          System.Threadin g.Thread.Sleep( 500)
          Loop
          End If
          Catch ex As IOException
          txtFolderActivi ty.Text &= "File " & sFileToImport & " was
          imported but IO Error " & ex.Message & " occurred while attempting to
          delete
          the previously imported file with the same name (" & Format(Now(),
          "m/d/yy
          hh:mm:ss") & ")." & vbCrLf
          Exit Sub
          End Try

          Try
          File.Move(textF ilesLocation & sFileToImport,
          textFilesLocati on
          &
          "ImportedNotice Files\" & sFileToImport)
          Catch ex As IOException
          txtFolderActivi ty.Text &= "IO Error " & ex.Message & "
          occurred
          while attempting to move file " & sFileToImport & " to the
          ImportedNoticeF iles folder. File NOT imported (" & Format(Now(), "m/d/yy
          hh:mm:ss") & ")." & vbCrLf
          Exit Sub
          End Try

          txtFolderActivi ty.Text &= "File " & sFileToImport & " has been
          imported successfully and has been moved to the ImportedNoticeF iles
          subfolder (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf

          End Sub

          End Class
          >
          >

          Comment

          • Keith G Hicks

            #6
            Re: IO errors with &quot;folder watcher&quot; program

            Well I added the following looping strategy (hack) to hopefully solve the
            problem of FileWatcherSyst em class trying to fire events multiple times and
            it seems to be working better:

            'Open the text file

            Dim iNumTries As Int16
            iNumTries = 0
            TryOpeningFile:
            If iNumTries 10 Then
            Exit Sub
            End If
            Try
            iNumTries += 1
            sr = New StreamReader(te xtFilesLocation & sFileToImport)
            Catch ex As Exception
            txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
            while trying to open file " & sFileToImport & ". File NOT imported (" &
            Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
            System.Threadin g.Thread.Sleep( 500)
            GoTo TryOpeningFile
            'Exit Sub
            End Try


            "Keith G Hicks" <krh@comcast.ne twrote in message
            news:e1FZ4E7BJH A.4368@TK2MSFTN GP06.phx.gbl...
            I'm having a lot of trouble with "file in use" errors in my "folder
            watcher"
            project. Starting and stopping the watcher and reading my XML file work
            fine. Once the watcher is started, I'm reading the text files from the
            watched folder line by line into variables and then posting them to a SQL
            table.
            >
            All of the code for the form is shown below. And it works fine except for
            2
            issues.
            >
            First issue: In the Finally of the Try for teh SQL code I have this:
            >
            sqlComm.Connect ion.Close()
            sqlComm.Dispose ()
            sqlConn.Dispose ()
            >
            I get this type of intellisense warning: "Variable sqlComm is used before
            it
            has been assigned a value. A null reference exception could result at
            runtime." What do I need to rearange to avoid this problem? Sometimes it
            causes crash and sometimes not. If the file cannot be opened for some
            reason, don't I want to free the sqlComm variable if the code fails?
            >
            Second issue (and this is the big problem really): IO errors. I run the
            program and then copy and paste 4 text files into the watched folder. They
            all get processed exactly as I expect. Everything below appears to run
            just
            fine. Then, without restartign the watcher program, I copy 4 different
            files
            into the watched folder. This time only 2 of them are processed. The other
            2
            generate the error below:
            >
            "The process cannot access the file 'D:\FilesToImpo rt\217068F01.tx t'
            because
            it is being used by another process."
            >
            Well it's not in use by anything I'm doing manually. I get this error
            pretty
            consistently when I do what I described above. Sometimes 2 files don't
            work
            and sometimes only 1. Sometimes they both process fine but that's very
            rare.
            Usually at least one of them fails. I have no idea why. It doesn't depend
            on
            the particular file either. It's always the first batch (whether it's 1
            file
            or 30) processes fine after I start up the watcher exe. Then when I drop
            any
            number of additional files into the watched folder 1 or more of them
            generate the error above.
            >
            I sure hope someone can point out the problems so I can get this running.
            I'm pretty frustrated with it right now.
            >
            Thanks,
            >
            Keith
            >
            >
            Here's all the code for this form:
            >
            >
            Imports System
            Imports System.Xml
            Imports System.IO
            Imports System.Diagnost ics
            Imports System.Data.Sql Client
            Imports System.Text.Reg ularExpressions
            >
            Public Class NoticeImport
            >
            Private watchFolder As FileSystemWatch er
            Private dataSource As String, _
            dataBase As String, _
            userName As String, _
            password As String, _
            monitoredCustom er As String, _
            textFilesLocati on As String, _
            fntName As String, _
            fntSize As Double, _
            clipWidth As String
            >
            Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
            System.EventArg s) Handles MyBase.Load
            btnStartWatchin g.Enabled = True
            btnStopWatching .Enabled = False
            Me.Text = "Monitoring for Customer: None"
            txtWatchFolder. Text = "Watching Folder: None "
            End Sub
            >
            Private Sub btnStartWatchin g_Click(ByVal sender As System.Object,
            ByVal
            e As System.EventArg s) Handles btnStartWatchin g.Click
            >
            watchFolder = New System.IO.FileS ystemWatcher()
            >
            'Get the db login info and the location of the input text files
            from
            the xml file
            >
            Dim sAppPathAndName As String = Application.Exe cutablePath
            Dim sAppPathOnly As String = Mid(sAppPathAnd Name, 1,
            InStr(sAppPathA ndName, "FNTNoticeImpor t.exe", CompareMethod.T ext) - 1)
            >
            textFilesLocati on = ""
            >
            Try
            >
            Dim xrdr As New XmlTextReader(s AppPathOnly &
            "FNTNoticeImpor tSettings.xml")
            xrdr.Whitespace Handling = WhitespaceHandl ing.None
            >
            While xrdr.Read()
            >
            If String.Compare( xrdr.Name, "dataSource ", True) = 0 Then
            dataSource = xrdr.ReadElemen tString()
            End If
            >
            If String.Compare( xrdr.Name, "dataBase", True) = 0 Then
            dataBase = xrdr.ReadElemen tString()
            End If
            >
            If String.Compare( xrdr.Name, "userName", True) = 0 Then
            userName = xrdr.ReadElemen tString()
            End If
            >
            If String.Compare( xrdr.Name, "password", True) = 0 Then
            password = xrdr.ReadElemen tString()
            End If
            >
            If String.Compare( xrdr.Name, "monitoredCusto mer", True) =
            0
            Then
            monitoredCustom er = xrdr.ReadElemen tString()
            End If
            >
            If String.Compare( xrdr.Name, "textFilesLocat ion", True) =
            0
            Then
            textFilesLocati on = xrdr.ReadElemen tString()
            End If
            >
            If String.Compare( xrdr.Name, "fntName", True) = 0 Then
            fntName = xrdr.ReadElemen tString()
            End If
            >
            If String.Compare( xrdr.Name, "fntSize", True) = 0 Then
            fntSize = xrdr.ReadElemen tString()
            End If
            >
            If String.Compare( xrdr.Name, "clipWidth" , True) = 0 Then
            clipWidth = xrdr.ReadElemen tString() 'clip width is in
            hundredths of an inch
            End If
            >
            End While
            >
            xrdr.Close()
            >
            'tell the watcher where to watch
            watchFolder.Pat h = textFilesLocati on
            Me.Text = "Monitoring for Customer: " & monitoredCustom er
            txtWatchFolder. Text = "Watching Folder: " & textFilesLocati on
            >
            'add a list of Filter we want to specify
            'make sure you use OR for each Filter as we need to all of
            those
            >
            watchFolder.Not ifyFilter = IO.NotifyFilter s.DirectoryName
            watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
            IO.NotifyFilter s.FileName
            watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
            IO.NotifyFilter s.Attributes
            >
            >
            ' add the handler to each event
            AddHandler watchFolder.Cha nged, AddressOf logChange
            AddHandler watchFolder.Cre ated, AddressOf logChange
            AddHandler watchFolder.Del eted, AddressOf logChange
            >
            ' add the rename handler as the signature is different
            AddHandler watchFolder.Ren amed, AddressOf logrename
            >
            'Set this property to true to start watching
            watchFolder.Ena bleRaisingEvent s = True
            watchFolder.Inc ludeSubdirector ies = False
            watchFolder.Fil ter = "*.txt"
            >
            btnStartWatchin g.Enabled = False
            btnStopWatching .Enabled = True
            >
            Catch ex As XmlException
            MsgBox("XML Error " & ex.Message & " occurred. Cannot start
            watching process.")
            Exit Sub
            >
            Catch ex As Exception
            MsgBox("Error " & ex.Message & " occurred. Cannot start
            watching
            process.")
            Exit Sub
            >
            End Try
            >
            End Sub
            >
            Private Sub logChange(ByVal source As Object, ByVal e As
            System.IO.FileS ystemEventArgs)
            >
            'Don't use this for now
            'If e.ChangeType = IO.WatcherChang eTypes.Changed Then
            ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
            modified" & vbCrLf
            'End If
            >
            If e.ChangeType = IO.WatcherChang eTypes.Created Then
            'txtFolderActiv ity.Text &= e.Name & " received at " & Now() &
            vbCrLf
            If InStr(e.Name, ".txt", CompareMethod.T ext) Then
            Call ImportTextFiles (e.Name)
            'Debug.Print(e. Name)
            End If
            End If
            >
            'Don't use this for now
            'If e.ChangeType = IO.WatcherChang eTypes.Deleted Then
            ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
            deleted" & vbCrLf
            'End If
            >
            End Sub
            >
            Public Sub logrename(ByVal source As Object, ByVal e As
            System.IO.Renam edEventArgs)
            'Don't use this for now
            'txtFolderActiv ity.Text &= "File" & e.OldName & " has been renamed
            to " & e.Name & vbCrLf
            End Sub
            >
            Private Sub btnStopWatching _Click(ByVal sender As System.Object, ByVal
            e
            As System.EventArg s) Handles btnStopWatching .Click
            ' Stop watching the folder
            watchFolder.Ena bleRaisingEvent s = False
            btnStartWatchin g.Enabled = True
            btnStopWatching .Enabled = False
            Me.Text = "Monitoring for Customer: None"
            txtWatchFolder. Text = "Watching Folder: None "
            End Sub
            >
            Private Sub ImportTextFiles (ByVal sFileToImport As String)
            >
            'Process the file
            >
            Dim dfc As New DlnpFntCalcs.Dl npFntCalcs
            Dim srLine As String
            Dim iFileLineCount As Integer, _
            iNoticeTextLine Count As Integer
            Dim bInNoticeText As Boolean
            Dim AdTypeCode As String, _
            ImportType As String, _
            AttorneyFileNum As String, _
            AttyOfficeName As String, _
            MortgagorFirstN ame As String, _
            MortgagorLastNa me As String, _
            PropAddress1 As String, _
            PropAddress2 As String, _
            PropCity As String, _
            PropState As String, _
            PropZip As String, _
            FirstPubDate As String, _
            NumWeeksToRun As String, _
            LastPubDate As String, _
            County As String, _
            DateOfSale As String, _
            FullNoticeText As String, _
            NoticeTextHeigh t As Double, _
            WholeImportFile As String
            >
            ImportType = ""
            AttorneyFileNum = ""
            AttyOfficeName = ""
            MortgagorFirstN ame = ""
            MortgagorLastNa me = ""
            PropAddress1 = ""
            PropAddress2 = ""
            PropCity = ""
            PropState = ""
            PropZip = ""
            FirstPubDate = ""
            NumWeeksToRun = ""
            LastPubDate = ""
            County = ""
            DateOfSale = ""
            FullNoticeText = ""
            WholeImportFile = ""
            >
            bInNoticeText = False
            iFileLineCount = 0
            iNoticeTextLine Count = 0
            >
            Dim sr As StreamReader
            >
            'Open the text file
            Try
            sr = New StreamReader(te xtFilesLocation & sFileToImport)
            Catch ex As Exception
            txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
            while trying to open file " & sFileToImport & ". File NOT imported (" &
            Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
            Exit Sub
            End Try
            >
            'Read the text file line by line
            Try
            Do
            srLine = sr.ReadLine()
            >
            iFileLineCount += 1
            If iFileLineCount = 1 Then
            WholeImportFile = srLine
            Else
            WholeImportFile = WholeImportFile & vbCrLf & srLine
            End If
            >
            'TODO 2008-08-13 - AdTypeCode will need to come from
            import
            file at some point
            AdTypeCode = "M"
            'If InStr(srLine, "Ad Tpe:", CompareMethod.T ext) Then
            ' AdTypeCode = Trim(Mid(srLine , 8))
            'End If
            >
            If InStr(srLine, "Publicatio n Notice:",
            CompareMethod.T ext)
            Then
            ImportType = Trim(Mid(srLine , 20))
            End If
            >
            If InStr(srLine, "File Number:", CompareMethod.T ext) Then
            AttorneyFileNum = Trim(Mid(srLine , 13))
            End If
            >
            'TODO 2008-08-13 - AttorneyName will need to come from
            import file at some point when we use this for other attorneys
            If InStr(srLine, "Team:", CompareMethod.T ext) Then
            AttyOfficeName = Trim(Mid(srLine , 6))
            AttyOfficeName = "Trott & Trott P.C. (team " &
            AttyOfficeName & ")"
            End If
            >
            If InStr(srLine, "Mortgagor First:", CompareMethod.T ext)
            Then
            MortgagorFirstN ame = Trim(Mid(srLine , 17))
            End If
            >
            If InStr(srLine, "Mortgagor Last:", CompareMethod.T ext)
            Then
            MortgagorLastNa me = Trim(Mid(srLine , 16))
            End If
            >
            If InStr(srLine, "Property Address 1:",
            CompareMethod.T ext)
            Then
            PropAddress1 = Trim(Mid(srLine , 20))
            End If
            >
            If InStr(srLine, "Property Address 2:",
            CompareMethod.T ext)
            Then
            PropAddress2 = Trim(Mid(srLine , 20))
            End If
            >
            If InStr(srLine, "City:", CompareMethod.T ext) Then
            PropCity = Trim(Mid(srLine , 6))
            End If
            >
            If InStr(srLine, "State:", CompareMethod.T ext) Then
            PropState = Trim(Mid(srLine , 7))
            End If
            >
            If InStr(srLine, "ZIP:", CompareMethod.T ext) Then
            PropZip = Trim(Mid(srLine , 5))
            End If
            >
            If InStr(srLine, "First Publication Date:",
            CompareMethod.T ext) Then
            FirstPubDate = Trim(Mid(srLine , 24))
            End If
            >
            If InStr(srLine, "Number Of Insertions:",
            CompareMethod.T ext) Then
            NumWeeksToRun = Trim(Mid(srLine , 22))
            End If
            >
            If InStr(srLine, "Last Pub Date:", CompareMethod.T ext)
            Then
            LastPubDate = Trim(Mid(srLine , 15))
            End If
            >
            If InStr(srLine, "County:", CompareMethod.T ext) Then
            County = Trim(Mid(srLine , 8))
            End If
            >
            If InStr(srLine, "Sale Date:", CompareMethod.T ext) Then
            DateOfSale = Trim(Mid(srLine , 11))
            End If
            >
            'TODO 2008-08-07 - only do the following if it's new or
            correction (not if cancel)
            If InStr(srLine, "*** Begin Notice ***",
            CompareMethod.T ext)
            0 Then
            'skip 1 line and read the rest into the FullNoticeText
            variable
            srLine = sr.ReadLine()
            iNoticeTextLine Count = 1 'we're on line one now and
            will
            get it into FullNoticeText below
            WholeImportFile = WholeImportFile & vbCrLf & srLine
            'have to do this here because we're skipping a line. if we don't then the
            similar line above won't catch the skipped line
            bInNoticeText = True
            End If
            >
            If bInNoticeText Then
            If InStr(srLine, "*** End Notice ***",
            CompareMethod.T ext) = 0 Then
            If iNoticeTextLine Count = 1 Then
            FullNoticeText = srLine
            Else
            FullNoticeText = FullNoticeText & vbCrLf &
            srLine
            End If
            iNoticeTextLine Count += 1
            End If
            End If
            >
            Loop Until InStr(srLine, "*** End Notice ***",
            CompareMethod.T ext) <0
            >
            >
            'If this is a correction, then there is info AFTER the "***
            End
            Notice ***" line that we need to read into the WholeImportFile variable
            If String.Compare( ImportType, "Correct", True) = 0 Then
            WholeImportFile = WholeImportFile & vbCrLf &
            sr.ReadToEnd()
            End If
            >
            Catch ex As Exception
            txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
            while trying to read file " & sFileToImport & ". File NOT imported (" &
            Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
            Exit Sub
            Finally
            'do not need sr after all the above reading is done
            sr.Close()
            sr.Dispose()
            End Try
            >
            >
            'get the height in decimal inches (rounded to 2 places)
            Try
            If FullNoticeText <"" Then
            NoticeTextHeigh t = (dfc.NoticeText Height(FullNoti ceText,
            fntName, fntSize, clipWidth))
            Else
            NoticeTextHeigh t = 0
            End If
            Catch ex As Exception
            txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
            while calling dll to get text height on file " & sFileToImport & ". File
            NOT
            imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
            Exit Sub
            End Try
            >
            >
            Dim sqlConn As SqlConnection
            Dim sqlComm As SqlCommand
            >
            'get the data into the database
            Try
            >
            sqlConn = New SqlConnection(" Data Source=" & dataSource &
            ";Initial Catalog=" & dataBase & ";User Id=" & userName & ";Password= " &
            password & ";")
            sqlConn.Open()
            >
            sqlComm = New SqlCommand("sp_ ImportNotices", sqlConn)
            sqlComm.Command Type = CommandType.Sto redProcedure
            >
            sqlComm.Paramet ers.Add("RETURN _VALUE", SqlDbType.Int). Value =
            0
            sqlComm.Paramet ers("RETURN_VAL UE").Directio n =
            ParameterDirect ion.ReturnValue
            sqlComm.Paramet ers.Add("@AdTyp eCode", SqlDbType.VarCh ar,
            50).Value = IIf(AdTypeCode = "", DBNull.Value, AdTypeCode)
            sqlComm.Paramet ers.Add("@Impor tType", SqlDbType.VarCh ar,
            50).Value = IIf(ImportType = "", DBNull.Value, ImportType)
            sqlComm.Paramet ers.Add("@Attor neyFileNum", SqlDbType.VarCh ar,
            50).Value = IIf(AttorneyFil eNum = "", DBNull.Value, AttorneyFileNum )
            sqlComm.Paramet ers.Add("@AttyO fficeName", SqlDbType.VarCh ar,
            200).Value = IIf(AttyOfficeN ame = "", DBNull.Value, AttyOfficeName)
            sqlComm.Paramet ers.Add("@Mortg agorFirstName",
            SqlDbType.VarCh ar,
            50).Value = IIf(MortgagorFi rstName = "", DBNull.Value, MortgagorFirstN ame)
            sqlComm.Paramet ers.Add("@Mortg agorLastName",
            SqlDbType.VarCh ar,
            50).Value = IIf(MortgagorLa stName = "", DBNull.Value, MortgagorLastNa me)
            sqlComm.Paramet ers.Add("@PropA ddress1", SqlDbType.VarCh ar,
            100).Value = IIf(PropAddress 1 = "", DBNull.Value, PropAddress1)
            sqlComm.Paramet ers.Add("@PropA ddress2", SqlDbType.VarCh ar,
            100).Value = IIf(PropAddress 2 = "", DBNull.Value, PropAddress2)
            sqlComm.Paramet ers.Add("@PropC ity", SqlDbType.VarCh ar,
            100).Value = IIf(PropCity = "", DBNull.Value, PropCity)
            sqlComm.Paramet ers.Add("@PropS tate", SqlDbType.VarCh ar,
            50).Value = IIf(PropState = "", DBNull.Value, PropState)
            sqlComm.Paramet ers.Add("@PropZ ip", SqlDbType.VarCh ar,
            20).Value
            = IIf(PropZip = "", DBNull.Value, PropZip)
            sqlComm.Paramet ers.Add("@First PubDate", SqlDbType.VarCh ar,
            50).Value = IIf(FirstPubDat e = "", DBNull.Value, FirstPubDate)
            sqlComm.Paramet ers.Add("@NumWe eksToRun", SqlDbType.VarCh ar,
            10).Value = IIf(NumWeeksToR un = "", DBNull.Value, NumWeeksToRun)
            sqlComm.Paramet ers.Add("@LastP ubDate", SqlDbType.VarCh ar,
            50).Value = IIf(LastPubDate = "", DBNull.Value, LastPubDate)
            sqlComm.Paramet ers.Add("@Count y", SqlDbType.VarCh ar, 50).Value
            =
            IIf(County = "", DBNull.Value, County)
            sqlComm.Paramet ers.Add("@DateO fSale", SqlDbType.VarCh ar,
            50).Value = IIf(DateOfSale = "", DBNull.Value, DateOfSale)
            sqlComm.Paramet ers.Add("@FullN oticeText",
            SqlDbType.Text) .Value
            = IIf(FullNoticeT ext = "", DBNull.Value, FullNoticeText)
            sqlComm.Paramet ers.Add("@Notic eTextHeight", SqlDbType.Decim al,
            5).Value = CDbl(NoticeText Height)
            sqlComm.Paramet ers.Add("@Whole ImportFile",
            SqlDbType.Text) .Value
            = IIf(WholeImport File = "", DBNull.Value, WholeImportFile )
            sqlComm.Paramet ers.Add("@TextF ileName", SqlDbType.VarCh ar,
            500).Value = sFileToImport
            sqlComm.Paramet ers.Add("@Reaso nsNotPosted", SqlDbType.VarCh ar,
            500).Value = DBNull.Value
            sqlComm.Paramet ers("@ReasonsNo tPosted").Direc tion =
            ParameterDirect ion.Output
            >
            sqlComm.Execute NonQuery()
            >
            If sqlComm.Paramet ers("RETURN_VAL UE").Value <0 Then
            txtFolderActivi ty.Text &= "SQL Error " &
            sqlComm.Paramet ers("RETURN_VAL UE").Value.ToSt ring & " on file " &
            sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss")
            &
            ")." & vbCrLf
            Exit Sub
            End If
            >
            Catch ex As SqlException
            txtFolderActivi ty.Text &= "SQL Error " & ex.Message & "
            occurred
            while executing SQL procedure sp_ImportNotice s on file " & sFileToImport &
            ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
            Exit Sub
            Catch ex As Exception
            txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
            while executing SQL procedure sp_ImportNotice s on file " & sFileToImport &
            ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
            Exit Sub
            Finally
            >
            sqlComm.Connect ion.Close()
            sqlComm.Dispose ()
            sqlConn.Dispose ()
            End Try
            >
            'if the "ImportedNotice Files" folder does not yet exist, create it
            Try
            If Not Directory.Exist s(textFilesLoca tion &
            "ImportedNotice Files") Then
            Directory.Creat eDirectory(text FilesLocation &
            "ImportedNotice Files")
            'don't go on until the folder has been created
            Do Until Directory.Exist s(textFilesLoca tion &
            "ImportedNotice Files")
            System.Threadin g.Thread.Sleep( 500)
            Loop
            End If
            Catch ex As IOException
            txtFolderActivi ty.Text &= "IO Error " & ex.Message & "
            attempting to create ImportedNoticeF iles folder while importing file " &
            sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss")
            &
            ")." & vbCrLf
            End Try
            >
            'store the finished file in the ImportedNoticeF iles folder for
            someone to manually review (delete it first if for some reason it already
            exists)
            Try
            If File.Exists(tex tFilesLocation & "ImportedNotice Files\" &
            sFileToImport) Then
            File.Delete(tex tFilesLocation & "ImportedNotice Files\" &
            sFileToImport)
            'Need to wait for the file to be deleted before moving on.
            Do Until Not File.Exists(tex tFilesLocation &
            "ImportedNotice Files\" & sFileToImport)
            System.Threadin g.Thread.Sleep( 500)
            Loop
            End If
            Catch ex As IOException
            txtFolderActivi ty.Text &= "File " & sFileToImport & " was
            imported but IO Error " & ex.Message & " occurred while attempting to
            delete
            the previously imported file with the same name (" & Format(Now(), "m/d/yy
            hh:mm:ss") & ")." & vbCrLf
            Exit Sub
            End Try
            >
            Try
            File.Move(textF ilesLocation & sFileToImport, textFilesLocati on
            &
            "ImportedNotice Files\" & sFileToImport)
            Catch ex As IOException
            txtFolderActivi ty.Text &= "IO Error " & ex.Message & "
            occurred
            while attempting to move file " & sFileToImport & " to the
            ImportedNoticeF iles folder. File NOT imported (" & Format(Now(), "m/d/yy
            hh:mm:ss") & ")." & vbCrLf
            Exit Sub
            End Try
            >
            txtFolderActivi ty.Text &= "File " & sFileToImport & " has been
            imported successfully and has been moved to the ImportedNoticeF iles
            subfolder (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
            >
            End Sub
            >
            End Class
            >
            >

            Comment

            • Keith G Hicks

              #7
              Re: IO errors with &quot;folder watcher&quot; program

              Still unpredictable. It helped but didn't completely solve the problem. Ugh.
              :-(

              "Keith G Hicks" <krh@comcast.ne twrote in message
              news:uv6xQhICJH A.3392@TK2MSFTN GP03.phx.gbl...
              Well I added the following looping strategy (hack) to hopefully solve the
              problem of FileWatcherSyst em class trying to fire events multiple times
              and
              it seems to be working better:
              >
              'Open the text file
              >
              Dim iNumTries As Int16
              iNumTries = 0
              TryOpeningFile:
              If iNumTries 10 Then
              Exit Sub
              End If
              Try
              iNumTries += 1
              sr = New StreamReader(te xtFilesLocation & sFileToImport)
              Catch ex As Exception
              txtFolderActivi ty.Text &= "Error " & ex.Message & "
              occurred
              while trying to open file " & sFileToImport & ". File NOT imported (" &
              Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
              System.Threadin g.Thread.Sleep( 500)
              GoTo TryOpeningFile
              'Exit Sub
              End Try
              >
              >
              "Keith G Hicks" <krh@comcast.ne twrote in message
              news:e1FZ4E7BJH A.4368@TK2MSFTN GP06.phx.gbl...
              I'm having a lot of trouble with "file in use" errors in my "folder
              watcher"
              project. Starting and stopping the watcher and reading my XML file work
              fine. Once the watcher is started, I'm reading the text files from the
              watched folder line by line into variables and then posting them to a
              SQL
              table.

              All of the code for the form is shown below. And it works fine except
              for
              2
              issues.

              First issue: In the Finally of the Try for teh SQL code I have this:

              sqlComm.Connect ion.Close()
              sqlComm.Dispose ()
              sqlConn.Dispose ()

              I get this type of intellisense warning: "Variable sqlComm is used
              before
              it
              has been assigned a value. A null reference exception could result at
              runtime." What do I need to rearange to avoid this problem? Sometimes it
              causes crash and sometimes not. If the file cannot be opened for some
              reason, don't I want to free the sqlComm variable if the code fails?

              Second issue (and this is the big problem really): IO errors. I run the
              program and then copy and paste 4 text files into the watched folder.
              They
              all get processed exactly as I expect. Everything below appears to run
              just
              fine. Then, without restartign the watcher program, I copy 4 different
              files
              into the watched folder. This time only 2 of them are processed. The
              other
              2
              generate the error below:

              "The process cannot access the file 'D:\FilesToImpo rt\217068F01.tx t'
              because
              it is being used by another process."

              Well it's not in use by anything I'm doing manually. I get this error
              pretty
              consistently when I do what I described above. Sometimes 2 files don't
              work
              and sometimes only 1. Sometimes they both process fine but that's very
              rare.
              Usually at least one of them fails. I have no idea why. It doesn't
              depend
              on
              the particular file either. It's always the first batch (whether it's 1
              file
              or 30) processes fine after I start up the watcher exe. Then when I drop
              any
              number of additional files into the watched folder 1 or more of them
              generate the error above.

              I sure hope someone can point out the problems so I can get this
              running.
              I'm pretty frustrated with it right now.

              Thanks,

              Keith


              Here's all the code for this form:


              Imports System
              Imports System.Xml
              Imports System.IO
              Imports System.Diagnost ics
              Imports System.Data.Sql Client
              Imports System.Text.Reg ularExpressions

              Public Class NoticeImport

              Private watchFolder As FileSystemWatch er
              Private dataSource As String, _
              dataBase As String, _
              userName As String, _
              password As String, _
              monitoredCustom er As String, _
              textFilesLocati on As String, _
              fntName As String, _
              fntSize As Double, _
              clipWidth As String

              Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
              System.EventArg s) Handles MyBase.Load
              btnStartWatchin g.Enabled = True
              btnStopWatching .Enabled = False
              Me.Text = "Monitoring for Customer: None"
              txtWatchFolder. Text = "Watching Folder: None "
              End Sub

              Private Sub btnStartWatchin g_Click(ByVal sender As System.Object,
              ByVal
              e As System.EventArg s) Handles btnStartWatchin g.Click

              watchFolder = New System.IO.FileS ystemWatcher()

              'Get the db login info and the location of the input text files
              from
              the xml file

              Dim sAppPathAndName As String = Application.Exe cutablePath
              Dim sAppPathOnly As String = Mid(sAppPathAnd Name, 1,
              InStr(sAppPathA ndName, "FNTNoticeImpor t.exe", CompareMethod.T ext) - 1)

              textFilesLocati on = ""

              Try

              Dim xrdr As New XmlTextReader(s AppPathOnly &
              "FNTNoticeImpor tSettings.xml")
              xrdr.Whitespace Handling = WhitespaceHandl ing.None

              While xrdr.Read()

              If String.Compare( xrdr.Name, "dataSource ", True) = 0
              Then
              dataSource = xrdr.ReadElemen tString()
              End If

              If String.Compare( xrdr.Name, "dataBase", True) = 0 Then
              dataBase = xrdr.ReadElemen tString()
              End If

              If String.Compare( xrdr.Name, "userName", True) = 0 Then
              userName = xrdr.ReadElemen tString()
              End If

              If String.Compare( xrdr.Name, "password", True) = 0 Then
              password = xrdr.ReadElemen tString()
              End If

              If String.Compare( xrdr.Name, "monitoredCusto mer", True)
              =
              0
              Then
              monitoredCustom er = xrdr.ReadElemen tString()
              End If

              If String.Compare( xrdr.Name, "textFilesLocat ion", True)
              =
              0
              Then
              textFilesLocati on = xrdr.ReadElemen tString()
              End If

              If String.Compare( xrdr.Name, "fntName", True) = 0 Then
              fntName = xrdr.ReadElemen tString()
              End If

              If String.Compare( xrdr.Name, "fntSize", True) = 0 Then
              fntSize = xrdr.ReadElemen tString()
              End If

              If String.Compare( xrdr.Name, "clipWidth" , True) = 0 Then
              clipWidth = xrdr.ReadElemen tString() 'clip width is
              in
              hundredths of an inch
              End If

              End While

              xrdr.Close()

              'tell the watcher where to watch
              watchFolder.Pat h = textFilesLocati on
              Me.Text = "Monitoring for Customer: " & monitoredCustom er
              txtWatchFolder. Text = "Watching Folder: " &
              textFilesLocati on

              'add a list of Filter we want to specify
              'make sure you use OR for each Filter as we need to all of
              those

              watchFolder.Not ifyFilter = IO.NotifyFilter s.DirectoryName
              watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
              IO.NotifyFilter s.FileName
              watchFolder.Not ifyFilter = watchFolder.Not ifyFilter Or
              IO.NotifyFilter s.Attributes


              ' add the handler to each event
              AddHandler watchFolder.Cha nged, AddressOf logChange
              AddHandler watchFolder.Cre ated, AddressOf logChange
              AddHandler watchFolder.Del eted, AddressOf logChange

              ' add the rename handler as the signature is different
              AddHandler watchFolder.Ren amed, AddressOf logrename

              'Set this property to true to start watching
              watchFolder.Ena bleRaisingEvent s = True
              watchFolder.Inc ludeSubdirector ies = False
              watchFolder.Fil ter = "*.txt"

              btnStartWatchin g.Enabled = False
              btnStopWatching .Enabled = True

              Catch ex As XmlException
              MsgBox("XML Error " & ex.Message & " occurred. Cannot start
              watching process.")
              Exit Sub

              Catch ex As Exception
              MsgBox("Error " & ex.Message & " occurred. Cannot start
              watching
              process.")
              Exit Sub

              End Try

              End Sub

              Private Sub logChange(ByVal source As Object, ByVal e As
              System.IO.FileS ystemEventArgs)

              'Don't use this for now
              'If e.ChangeType = IO.WatcherChang eTypes.Changed Then
              ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
              modified" & vbCrLf
              'End If

              If e.ChangeType = IO.WatcherChang eTypes.Created Then
              'txtFolderActiv ity.Text &= e.Name & " received at " & Now()
              &
              vbCrLf
              If InStr(e.Name, ".txt", CompareMethod.T ext) Then
              Call ImportTextFiles (e.Name)
              'Debug.Print(e. Name)
              End If
              End If

              'Don't use this for now
              'If e.ChangeType = IO.WatcherChang eTypes.Deleted Then
              ' txtFolderActivi ty.Text &= "File " & e.FullPath & " has been
              deleted" & vbCrLf
              'End If

              End Sub

              Public Sub logrename(ByVal source As Object, ByVal e As
              System.IO.Renam edEventArgs)
              'Don't use this for now
              'txtFolderActiv ity.Text &= "File" & e.OldName & " has been
              renamed
              to " & e.Name & vbCrLf
              End Sub

              Private Sub btnStopWatching _Click(ByVal sender As System.Object,
              ByVal
              e
              As System.EventArg s) Handles btnStopWatching .Click
              ' Stop watching the folder
              watchFolder.Ena bleRaisingEvent s = False
              btnStartWatchin g.Enabled = True
              btnStopWatching .Enabled = False
              Me.Text = "Monitoring for Customer: None"
              txtWatchFolder. Text = "Watching Folder: None "
              End Sub

              Private Sub ImportTextFiles (ByVal sFileToImport As String)

              'Process the file

              Dim dfc As New DlnpFntCalcs.Dl npFntCalcs
              Dim srLine As String
              Dim iFileLineCount As Integer, _
              iNoticeTextLine Count As Integer
              Dim bInNoticeText As Boolean
              Dim AdTypeCode As String, _
              ImportType As String, _
              AttorneyFileNum As String, _
              AttyOfficeName As String, _
              MortgagorFirstN ame As String, _
              MortgagorLastNa me As String, _
              PropAddress1 As String, _
              PropAddress2 As String, _
              PropCity As String, _
              PropState As String, _
              PropZip As String, _
              FirstPubDate As String, _
              NumWeeksToRun As String, _
              LastPubDate As String, _
              County As String, _
              DateOfSale As String, _
              FullNoticeText As String, _
              NoticeTextHeigh t As Double, _
              WholeImportFile As String

              ImportType = ""
              AttorneyFileNum = ""
              AttyOfficeName = ""
              MortgagorFirstN ame = ""
              MortgagorLastNa me = ""
              PropAddress1 = ""
              PropAddress2 = ""
              PropCity = ""
              PropState = ""
              PropZip = ""
              FirstPubDate = ""
              NumWeeksToRun = ""
              LastPubDate = ""
              County = ""
              DateOfSale = ""
              FullNoticeText = ""
              WholeImportFile = ""

              bInNoticeText = False
              iFileLineCount = 0
              iNoticeTextLine Count = 0

              Dim sr As StreamReader

              'Open the text file
              Try
              sr = New StreamReader(te xtFilesLocation & sFileToImport)
              Catch ex As Exception
              txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
              while trying to open file " & sFileToImport & ". File NOT imported (" &
              Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
              Exit Sub
              End Try

              'Read the text file line by line
              Try
              Do
              srLine = sr.ReadLine()

              iFileLineCount += 1
              If iFileLineCount = 1 Then
              WholeImportFile = srLine
              Else
              WholeImportFile = WholeImportFile & vbCrLf & srLine
              End If

              'TODO 2008-08-13 - AdTypeCode will need to come from
              import
              file at some point
              AdTypeCode = "M"
              'If InStr(srLine, "Ad Tpe:", CompareMethod.T ext) Then
              ' AdTypeCode = Trim(Mid(srLine , 8))
              'End If

              If InStr(srLine, "Publicatio n Notice:",
              CompareMethod.T ext)
              Then
              ImportType = Trim(Mid(srLine , 20))
              End If

              If InStr(srLine, "File Number:", CompareMethod.T ext)
              Then
              AttorneyFileNum = Trim(Mid(srLine , 13))
              End If

              'TODO 2008-08-13 - AttorneyName will need to come from
              import file at some point when we use this for other attorneys
              If InStr(srLine, "Team:", CompareMethod.T ext) Then
              AttyOfficeName = Trim(Mid(srLine , 6))
              AttyOfficeName = "Trott & Trott P.C. (team " &
              AttyOfficeName & ")"
              End If

              If InStr(srLine, "Mortgagor First:", CompareMethod.T ext)
              Then
              MortgagorFirstN ame = Trim(Mid(srLine , 17))
              End If

              If InStr(srLine, "Mortgagor Last:", CompareMethod.T ext)
              Then
              MortgagorLastNa me = Trim(Mid(srLine , 16))
              End If

              If InStr(srLine, "Property Address 1:",
              CompareMethod.T ext)
              Then
              PropAddress1 = Trim(Mid(srLine , 20))
              End If

              If InStr(srLine, "Property Address 2:",
              CompareMethod.T ext)
              Then
              PropAddress2 = Trim(Mid(srLine , 20))
              End If

              If InStr(srLine, "City:", CompareMethod.T ext) Then
              PropCity = Trim(Mid(srLine , 6))
              End If

              If InStr(srLine, "State:", CompareMethod.T ext) Then
              PropState = Trim(Mid(srLine , 7))
              End If

              If InStr(srLine, "ZIP:", CompareMethod.T ext) Then
              PropZip = Trim(Mid(srLine , 5))
              End If

              If InStr(srLine, "First Publication Date:",
              CompareMethod.T ext) Then
              FirstPubDate = Trim(Mid(srLine , 24))
              End If

              If InStr(srLine, "Number Of Insertions:",
              CompareMethod.T ext) Then
              NumWeeksToRun = Trim(Mid(srLine , 22))
              End If

              If InStr(srLine, "Last Pub Date:", CompareMethod.T ext)
              Then
              LastPubDate = Trim(Mid(srLine , 15))
              End If

              If InStr(srLine, "County:", CompareMethod.T ext) Then
              County = Trim(Mid(srLine , 8))
              End If

              If InStr(srLine, "Sale Date:", CompareMethod.T ext) Then
              DateOfSale = Trim(Mid(srLine , 11))
              End If

              'TODO 2008-08-07 - only do the following if it's new or
              correction (not if cancel)
              If InStr(srLine, "*** Begin Notice ***",
              CompareMethod.T ext)
              0 Then
              'skip 1 line and read the rest into the
              FullNoticeText
              variable
              srLine = sr.ReadLine()
              iNoticeTextLine Count = 1 'we're on line one now and
              will
              get it into FullNoticeText below
              WholeImportFile = WholeImportFile & vbCrLf & srLine
              'have to do this here because we're skipping a line. if we don't then
              the
              similar line above won't catch the skipped line
              bInNoticeText = True
              End If

              If bInNoticeText Then
              If InStr(srLine, "*** End Notice ***",
              CompareMethod.T ext) = 0 Then
              If iNoticeTextLine Count = 1 Then
              FullNoticeText = srLine
              Else
              FullNoticeText = FullNoticeText & vbCrLf &
              srLine
              End If
              iNoticeTextLine Count += 1
              End If
              End If

              Loop Until InStr(srLine, "*** End Notice ***",
              CompareMethod.T ext) <0


              'If this is a correction, then there is info AFTER the "***
              End
              Notice ***" line that we need to read into the WholeImportFile variable
              If String.Compare( ImportType, "Correct", True) = 0 Then
              WholeImportFile = WholeImportFile & vbCrLf &
              sr.ReadToEnd()
              End If

              Catch ex As Exception
              txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
              while trying to read file " & sFileToImport & ". File NOT imported (" &
              Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
              Exit Sub
              Finally
              'do not need sr after all the above reading is done
              sr.Close()
              sr.Dispose()
              End Try


              'get the height in decimal inches (rounded to 2 places)
              Try
              If FullNoticeText <"" Then
              NoticeTextHeigh t = (dfc.NoticeText Height(FullNoti ceText,
              fntName, fntSize, clipWidth))
              Else
              NoticeTextHeigh t = 0
              End If
              Catch ex As Exception
              txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
              while calling dll to get text height on file " & sFileToImport & ". File
              NOT
              imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf
              Exit Sub
              End Try


              Dim sqlConn As SqlConnection
              Dim sqlComm As SqlCommand

              'get the data into the database
              Try

              sqlConn = New SqlConnection(" Data Source=" & dataSource &
              ";Initial Catalog=" & dataBase & ";User Id=" & userName & ";Password= " &
              password & ";")
              sqlConn.Open()

              sqlComm = New SqlCommand("sp_ ImportNotices", sqlConn)
              sqlComm.Command Type = CommandType.Sto redProcedure

              sqlComm.Paramet ers.Add("RETURN _VALUE", SqlDbType.Int). Value
              =
              0
              sqlComm.Paramet ers("RETURN_VAL UE").Directio n =
              ParameterDirect ion.ReturnValue
              sqlComm.Paramet ers.Add("@AdTyp eCode", SqlDbType.VarCh ar,
              50).Value = IIf(AdTypeCode = "", DBNull.Value, AdTypeCode)
              sqlComm.Paramet ers.Add("@Impor tType", SqlDbType.VarCh ar,
              50).Value = IIf(ImportType = "", DBNull.Value, ImportType)
              sqlComm.Paramet ers.Add("@Attor neyFileNum",
              SqlDbType.VarCh ar,
              50).Value = IIf(AttorneyFil eNum = "", DBNull.Value, AttorneyFileNum )
              sqlComm.Paramet ers.Add("@AttyO fficeName", SqlDbType.VarCh ar,
              200).Value = IIf(AttyOfficeN ame = "", DBNull.Value, AttyOfficeName)
              sqlComm.Paramet ers.Add("@Mortg agorFirstName",
              SqlDbType.VarCh ar,
              50).Value = IIf(MortgagorFi rstName = "", DBNull.Value,
              MortgagorFirstN ame)
              sqlComm.Paramet ers.Add("@Mortg agorLastName",
              SqlDbType.VarCh ar,
              50).Value = IIf(MortgagorLa stName = "", DBNull.Value, MortgagorLastNa me)
              sqlComm.Paramet ers.Add("@PropA ddress1", SqlDbType.VarCh ar,
              100).Value = IIf(PropAddress 1 = "", DBNull.Value, PropAddress1)
              sqlComm.Paramet ers.Add("@PropA ddress2", SqlDbType.VarCh ar,
              100).Value = IIf(PropAddress 2 = "", DBNull.Value, PropAddress2)
              sqlComm.Paramet ers.Add("@PropC ity", SqlDbType.VarCh ar,
              100).Value = IIf(PropCity = "", DBNull.Value, PropCity)
              sqlComm.Paramet ers.Add("@PropS tate", SqlDbType.VarCh ar,
              50).Value = IIf(PropState = "", DBNull.Value, PropState)
              sqlComm.Paramet ers.Add("@PropZ ip", SqlDbType.VarCh ar,
              20).Value
              = IIf(PropZip = "", DBNull.Value, PropZip)
              sqlComm.Paramet ers.Add("@First PubDate", SqlDbType.VarCh ar,
              50).Value = IIf(FirstPubDat e = "", DBNull.Value, FirstPubDate)
              sqlComm.Paramet ers.Add("@NumWe eksToRun", SqlDbType.VarCh ar,
              10).Value = IIf(NumWeeksToR un = "", DBNull.Value, NumWeeksToRun)
              sqlComm.Paramet ers.Add("@LastP ubDate", SqlDbType.VarCh ar,
              50).Value = IIf(LastPubDate = "", DBNull.Value, LastPubDate)
              sqlComm.Paramet ers.Add("@Count y", SqlDbType.VarCh ar,
              50).Value
              =
              IIf(County = "", DBNull.Value, County)
              sqlComm.Paramet ers.Add("@DateO fSale", SqlDbType.VarCh ar,
              50).Value = IIf(DateOfSale = "", DBNull.Value, DateOfSale)
              sqlComm.Paramet ers.Add("@FullN oticeText",
              SqlDbType.Text) .Value
              = IIf(FullNoticeT ext = "", DBNull.Value, FullNoticeText)
              sqlComm.Paramet ers.Add("@Notic eTextHeight",
              SqlDbType.Decim al,
              5).Value = CDbl(NoticeText Height)
              sqlComm.Paramet ers.Add("@Whole ImportFile",
              SqlDbType.Text) .Value
              = IIf(WholeImport File = "", DBNull.Value, WholeImportFile )
              sqlComm.Paramet ers.Add("@TextF ileName", SqlDbType.VarCh ar,
              500).Value = sFileToImport
              sqlComm.Paramet ers.Add("@Reaso nsNotPosted",
              SqlDbType.VarCh ar,
              500).Value = DBNull.Value
              sqlComm.Paramet ers("@ReasonsNo tPosted").Direc tion =
              ParameterDirect ion.Output

              sqlComm.Execute NonQuery()

              If sqlComm.Paramet ers("RETURN_VAL UE").Value <0 Then
              txtFolderActivi ty.Text &= "SQL Error " &
              sqlComm.Paramet ers("RETURN_VAL UE").Value.ToSt ring & " on file " &
              sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy
              hh:mm:ss")
              &
              ")." & vbCrLf
              Exit Sub
              End If

              Catch ex As SqlException
              txtFolderActivi ty.Text &= "SQL Error " & ex.Message & "
              occurred
              while executing SQL procedure sp_ImportNotice s on file " & sFileToImport
              &
              ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." &
              vbCrLf
              Exit Sub
              Catch ex As Exception
              txtFolderActivi ty.Text &= "Error " & ex.Message & " occurred
              while executing SQL procedure sp_ImportNotice s on file " & sFileToImport
              &
              ". File NOT imported (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." &
              vbCrLf
              Exit Sub
              Finally

              sqlComm.Connect ion.Close()
              sqlComm.Dispose ()
              sqlConn.Dispose ()
              End Try

              'if the "ImportedNotice Files" folder does not yet exist, create
              it
              Try
              If Not Directory.Exist s(textFilesLoca tion &
              "ImportedNotice Files") Then
              Directory.Creat eDirectory(text FilesLocation &
              "ImportedNotice Files")
              'don't go on until the folder has been created
              Do Until Directory.Exist s(textFilesLoca tion &
              "ImportedNotice Files")
              System.Threadin g.Thread.Sleep( 500)
              Loop
              End If
              Catch ex As IOException
              txtFolderActivi ty.Text &= "IO Error " & ex.Message & "
              attempting to create ImportedNoticeF iles folder while importing file " &
              sFileToImport & ". File NOT imported (" & Format(Now(), "m/d/yy
              hh:mm:ss")
              &
              ")." & vbCrLf
              End Try

              'store the finished file in the ImportedNoticeF iles folder for
              someone to manually review (delete it first if for some reason it
              already
              exists)
              Try
              If File.Exists(tex tFilesLocation & "ImportedNotice Files\" &
              sFileToImport) Then
              File.Delete(tex tFilesLocation & "ImportedNotice Files\" &
              sFileToImport)
              'Need to wait for the file to be deleted before moving
              on.
              Do Until Not File.Exists(tex tFilesLocation &
              "ImportedNotice Files\" & sFileToImport)
              System.Threadin g.Thread.Sleep( 500)
              Loop
              End If
              Catch ex As IOException
              txtFolderActivi ty.Text &= "File " & sFileToImport & " was
              imported but IO Error " & ex.Message & " occurred while attempting to
              delete
              the previously imported file with the same name (" & Format(Now(),
              "m/d/yy
              hh:mm:ss") & ")." & vbCrLf
              Exit Sub
              End Try

              Try
              File.Move(textF ilesLocation & sFileToImport,
              textFilesLocati on
              &
              "ImportedNotice Files\" & sFileToImport)
              Catch ex As IOException
              txtFolderActivi ty.Text &= "IO Error " & ex.Message & "
              occurred
              while attempting to move file " & sFileToImport & " to the
              ImportedNoticeF iles folder. File NOT imported (" & Format(Now(), "m/d/yy
              hh:mm:ss") & ")." & vbCrLf
              Exit Sub
              End Try

              txtFolderActivi ty.Text &= "File " & sFileToImport & " has been
              imported successfully and has been moved to the ImportedNoticeF iles
              subfolder (" & Format(Now(), "m/d/yy hh:mm:ss") & ")." & vbCrLf

              End Sub

              End Class
              >
              >

              Comment

              • Steve Gerrard

                #8
                Re: IO errors with &quot;folder watcher&quot; program

                Keith G Hicks wrote:
                Still unpredictable. It helped but didn't completely solve the
                problem. Ugh. :-(
                >
                I think you will run into trouble as long as you try to process files within the
                FileWatcher event handler.

                A better strategy is to use the events to build a ToDo list for yourself, and to
                start a timer on say a 0.5 sec interval. When the timer fires, turn it off and
                process one file from the list. If there are more entries in the list, turn on
                the timer again.

                This decouples file processing from notification. Unless you do this, you may
                miss some notifications. The file processing should anticipate that it may not
                be able to open the file, in which case it simply turns on the timer again, and
                tries again after another 0.5 second.

                I have a Windows service monitoring an SMTP drop folder, and this kind of
                decoupling was essential to get it to work right. Goes like clockwork now.


                Comment

                • Keith G Hicks

                  #9
                  Re: IO errors with &quot;folder watcher&quot; program

                  Thanks for the feedback Steve. In fact that was what I first set up before I
                  found out about the FileSystemWatch er class. I had set up a routine to look
                  for text files in the folder (just using the DIR funciton) and then store
                  the file names in an array. Then I'd loop through the array to get the
                  contents of each file. I discovered the FileSystemWatch er class before I got
                  around to putting the timer into the mix so I abandoned my earlier code. I
                  went to bed last night thinking I would probably have to do something like
                  what you suggested but was not sure how to handle the problem of files
                  coming in while processing was happening. Your suggestion about turning off
                  the timer solves that.

                  Just so I know I'm clear, are you suggesting using a timer INSTEAD OF the
                  FileSystemWatch er class altogether or somehow in conjunction with it? If the
                  former, I know what I need to do. If the later, I'm not entirely sure how
                  I'd combine the efforts of a timer along with the FileSystemWatch er class.
                  Do you mean to use the FileSystemWatch er to build the "todo" list and then
                  turn off the FileSystemWatch er and the timer? I'm a little fuzzy on the
                  specifics.

                  Thanks again,

                  Keith

                  "Steve Gerrard" <mynamehere@com cast.netwrote in message
                  news:AfqdnX2Na6 NFXivVnZ2dnUVZ_ rDinZ2d@comcast .com...
                  Keith G Hicks wrote:
                  Still unpredictable. It helped but didn't completely solve the
                  problem. Ugh. :-(
                  >
                  I think you will run into trouble as long as you try to process files
                  within the
                  FileWatcher event handler.
                  >
                  A better strategy is to use the events to build a ToDo list for yourself,
                  and to
                  start a timer on say a 0.5 sec interval. When the timer fires, turn it off
                  and
                  process one file from the list. If there are more entries in the list,
                  turn on
                  the timer again.
                  >
                  This decouples file processing from notification. Unless you do this, you
                  may
                  miss some notifications. The file processing should anticipate that it may
                  not
                  be able to open the file, in which case it simply turns on the timer
                  again, and
                  tries again after another 0.5 second.
                  >
                  I have a Windows service monitoring an SMTP drop folder, and this kind of
                  decoupling was essential to get it to work right. Goes like clockwork now.
                  >
                  >

                  Comment

                  • Steve Gerrard

                    #10
                    Re: IO errors with &quot;folder watcher&quot; program

                    Keith G Hicks wrote:
                    >
                    Just so I know I'm clear, are you suggesting using a timer INSTEAD OF
                    the FileSystemWatch er class altogether or somehow in conjunction with
                    it? If the former, I know what I need to do. If the later, I'm not
                    entirely sure how I'd combine the efforts of a timer along with the
                    FileSystemWatch er class. Do you mean to use the FileSystemWatch er to
                    build the "todo" list and then turn off the FileSystemWatch er and the
                    timer? I'm a little fuzzy on the specifics.
                    >
                    In my case, I process one file at a time, set the timer, look for a file,
                    process it, set the timer, until there are no files. Then I turn on the
                    FileSystemWatch er. At that point the service goes idle; it gets woken up when a
                    file shows up in the folder. When that happens, the FileSystemWatch er gets
                    turned off, the timer gets turned on, and the timer/file processing sequence
                    repeats until there are no more files again.

                    You may want to leave the FileSystemWatch er on, since you need to know more
                    about what happened (I am only looking for new files). I would have the
                    FileSystemWatch er event put things in a list, and a timer run some code to take
                    them out and do them one at a time. When there is nothing to do, turn off the
                    timer, and wait for the FileSystemWatch er to wake things up again. If want (or
                    need) to be really slick, you could do all the actual file processing in a
                    background worker thread, so the main thread can always be ready to process
                    FileSystemWatch er events.


                    Comment

                    Working...