Process cannot access the file because it is beging used by another process

AdrianGarcia used Ask the Experts™
I am using and XML to take some information, but when the program processed more of 5 file apper the error mentioned in the title some body help me
Private Sub FileSystemWatcher1_Changed(ByVal sender As System.Object, ByVal e As System.IO.FileSystemEventArgs) Handles FSW.Changed
        Dim xmld As New XmlDocument
        Dim sr As StreamReader

        Dim nodelist As XmlNodeList
        Dim node As XmlNode
        Dim nodelist1 As XmlNodeList
        Dim node1 As XmlNode
        Dim Modelo As String
        Dim conn As OleDbConnection
        Dim myCmd As New OleDbCommand
        Dim sqlstring As String
        Dim sqlstring1 As String
        Dim Noencontro As Integer
        Dim i As Integer
        Dim isError As Boolean = True
        Noencontro = 0
        g = 0

        C = C + 1
        Cagain(C) = e.Name

        While isError

                If Cagain(1) <> Cagain(2) Then
                    If My.Computer.FileSystem.FileExists(Campos(1) & e.Name) Then
                        Dim infoReader As System.IO.FileInfo
                        infoReader = My.Computer.FileSystem.GetFileInfo(Campos(1) & e.Name)

                        If infoReader.Length <> 0 Then

                            Dim SPath As String = Campos(1) & e.Name
                            Dim sContent As String = vbNullString

                            With My.Computer.FileSystem
                                ' verifica si existe el path  
                                If .FileExists(SPath) Then
                                    ' lee todo el contenido  
                                    sContent = .ReadAllText(SPath)
                                    If InStr(sContent, "event") Then
                                        If InStr(sContent, "info") Then
                                            If InStr(sContent, "uutstate") Then

                                                'Cargamos el documento XML

                                                sr = New StreamReader(Campos(1) & e.Name)

                                                'xmld.Load(Campos(1) & e.Name)
                                                nodelist = xmld.SelectNodes("/event/info")
                                                'Recorremos cada nodo
                                                For Each node In nodelist
                                                    g = g + 1
                                                    'Recogemos el valor del Fabricante
                                                    CCampos(g) = node.Attributes.GetNamedItem("value").Value
                                                    'Recorremos la lista de hijos
                                                    'For I As Integer = 1 To node.ChildNodes.Count
                                                    'CCampos(g) = node.ChildNodes.Item(I - 1).InnerText
                                                    'Mostramos la información en pantalla
                                                    'MessageBox.Show(Fabricante & vbCrLf & Modelo)
                                                    'Recogemos el valor del Modelo100
                                                'Cargamos el documento XML
                                                nodelist1 = xmld.SelectNodes("/event/uutstate")
                                                'Recorremos cada nodo

                                                For Each node1 In nodelist1

                                                    'Recogemos el valor del Fabricante
                                                    CCampos(g + 1) = node1.Attributes.GetNamedItem("value").Value
                                                    CCampos(g + 2) = node1.Attributes.GetNamedItem("timestamp").Value
                                                    CCampos(g + 3) = node1.Attributes.GetNamedItem("process").Value

                                                    'Recorremos la lista de hijos
                                                    'For I As Integer = 1 To node1.ChildNodes.Count
                                                    'Modelo = node1.ChildNodes.Item(I - 1).InnerText
                                                    'Mostramos la información en pantalla
                                                    'MessageBox.Show(Fabricante & vbCrLf & Modelo)
                                                    'Recogemos el valor del Modelo100
                                                xmld = Nothing
                                                nodelist = Nothing
                                                nodelist1 = Nothing
                                                node = Nothing
                                                node1 = Nothing

                                                conn = New OleDbConnection("Provider=SQLOLEDB;Server=jzenblackbox3;Database=RuninTiming;UID=bpc;Pwd=bpctest;")

                                                If conn.State = ConnectionState.Closed Then conn.Open()

                                                sqlstring1 = "Select * from LogEventTool with(nolock) Where Serial_Number='" & Trim(CCampos(12)) & "'and " _
                                                 & " uutstate='" & Trim(CCampos(13)) & "' and timestamp='" & Trim(CCampos(14)) & "' and process='" & Trim(CCampos(15)) & "' "

                                                'sqlstring1 = "Select * from LogEventTool with(nolock) Where Serial_Number='MXL1111111'"
                                                '& "and UUTSTATE='" & mTiempo1 & "'"
                                                myCmd = New OleDbCommand(sqlstring1, conn)
                                                Dim oledbReader As OleDbDataReader = myCmd.ExecuteReader()
                                                While oledbReader.Read
                                                    Noencontro = 1
                                                    'cacas = oledbReader.Item(0)
                                                    'cacas1 = oledbReader.Item(1)
                                                    'cacas2 = oledbReader.Item(2)

                                                    'sqlstring = "Update LogEventTool " _
                                                    ' & "Set " _
                                                    ' & "FechaDetection='" & Now() & "' Where Serial_Number='" & Trim(Campos(12)) & "'"

                                                    '& "Set uutstate='" & mTiempo1 & "',timestamp='" & mValue1 & "',process='" & mProcess1 & "', " _
                                                    'myCmd = New OleDbCommand(sqlstring, conn)

                                                    'MsgBox(oledbReader.Item(0) & "  -  " & oledbReader.Item(1) & "  -  " & oledbReader.Item(2))
                                                End While

                                                If Noencontro = 0 Then
                                                    sqlstring = "insert into LogEventTool(Boot_Environment,BuildID,POSKU_Number,Prism_Server," _
                                                    & "Product_Number,Server_Tools_Version,Servergate_IP,SkeletonPO,SKU_Revision,Toolset_Version, " _
                                                    & "MAC,Serial_Number,uutstate,timestamp,process,FechaDetection) " _
                                                    & "values ( '" & Trim(CCampos(1)) & "','" & Trim(CCampos(2)) & "'" _
                                                    & ",'" & Trim(CCampos(3)) & "','" & Trim(CCampos(4)) & "','" & Trim(CCampos(5)) & "','" & Trim(CCampos(6)) & "' " _
                                                    & ",'" & Trim(CCampos(7)) & "','" & Trim(CCampos(8)) & "','" & Trim(CCampos(9)) & "','" & Trim(CCampos(10)) & "' " _
                                                    & ",'" & Trim(CCampos(11)) & "','" & Trim(CCampos(12)) & "' " _
                                                    & ",'" & Trim(CCampos(13)) & "','" & Trim(CCampos(14)) & "','" & Trim(CCampos(15)) & "','" & Now() & "')"
                                                    '   sqlstring = "Update LogEventTool" _
                                                    '   & "Set uutstate='" & mTiempo1 & "',timestamp='" & mValue1 & "',process='" & mProcess1 & "', " _
                                                    '  & "FechaDetection='" & Now() & "' Where Serial_Number='" & Trim(Campos(12)) & "'"
                                                    myCmd = New OleDbCommand(sqlstring, conn)
                                                End If
                                                If My.Computer.FileSystem.DirectoryExists(Campos(1)) Then
                                                    'logInfo = My.Computer.FileSystem.GetDirectoryInfo _

                                                    My.Computer.FileSystem.CopyFile( _
                                                      " " & Campos(1) & "" & e.Name & " ", _
                                                      " " & Campos(2) & "" & e.Name & "", True)
                                                    'If My.Computer.FileSystem.FileExists("C:\LogXml\Backup\" & e.Name & "") Then

                                                    'My.Computer.FileSystem.MoveFile("S:\BootImage\" & e.Name & " ", _
                                                    '   "C:\LogXml\Backup\" & e.Name & "", True)
                                                    'End If

                                                End If
                                            End If
                                        End If

                                    End If
                                    'MsgBox(sContent.ToString, MsgBoxStyle.Information, "Datos")
                                    MsgBox("ruta inválida", MsgBoxStyle.Critical, "error")
                                End If
                            End With

                        End If

                    End If
                    C = 0
                    g = 0
                    Cagain(1) = Nothing
                    Cagain(2) = Nothing

                    For i = 0 To 15
                        CCampos(i) = Nothing
                        'Campos(i) = Nothing

                End If
                ' errores
                isError = False

            Catch ex As Exception
                MsgBox(ex.Message.ToString, MsgBoxStyle.Critical)
                MsgBox("g " & g)
                MsgBox("i " & i)
                MsgBox("C " & C)


            End Try
        End While
    End Sub
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2012
Top Expert 2008

Are you processing file changes for the same file, or multiple files?


I am processing multiple Files
Most Valuable Expert 2012
Top Expert 2008

There is a lot going on there, so can you summarize the steps, rather than me looking through all that detail?
Expert Spotlight: Joe Anderson (DatabaseMX)

We’ve posted a new Expert Spotlight!  Joe Anderson (DatabaseMX) has been on Experts Exchange since 2006. Learn more about this database architect, guitar aficionado, and Microsoft MVP.


Sorry for my english I Try to explain the steps

1.-We have a process that generated the XML for unit ever 10 or 20 seconds
2.-I need to read all the XML generated and save the information in SQL Server
3.- I need to save the Atrribute "Value" from Info
4.-I need to save the atribute "value,timestamp,process" from uutstate
Here you go and example of the XML  
<?xml version="1.0" encoding="utf-8" ?>
<event><info name="Boot Environment" value="Build 53.7.12" />
<info name="BuildID" value="11WWCSGW302#SABA#DABA" />
<info name="PO/SKU Number" value="MXL2130KJC_DPS" />
<info name="Prism Server" value="" />
<info name="Product Number" value="H2V31US#ABA" />
<info name="Server Tools Version" value="Build 53.7.12" />
<info name="Servergate IP" value="" />
<info name="SkeletonPO" value="4705164742-00001" />
<info name="SKU Revision" value="FALSE" />
<info name="Toolset Version" value="" />
<info name="MAC" value="9C8E99DD20D0" />
<info name="Serial Number" value="MXL2130KJC" />
<uutstate value="PRETEST" timestamp="201203290655" process="NETWORK" />
Most Valuable Expert 2012
Top Expert 2008

Thank you for the explanation.  I try to get bogged down by English phrasing, as I understand that English is not native to everyone that posts questions here--so don't worry about me.

I believe that you need to determine which process has the file locked, but I will start by assuming that it is your application.   There are many different reasons for file locking--some you can see from your code, and some you can't.  

Some ideas are:

1) Multiple threads trying to access

2) Opening a file stream, and not closing it

3) Some classes use a file stream internally, but usually implement IDisposable.  It is a good practice to have a Using block, where possible, to automatically call the Dispose method for any class that implements IDisposable.

4) Multiple events from the FileSystemWatcher referencing the same file name.


for the points that you mentioned

2.-How do I to Close the Stream or the XMLDocument ? I think that the problem is with the XMLDocument

3.- How do I to know wich class is call the IDisposable?

4.- I saw the FileSystemWatcher Processed 2 time the file for each detection.

Do you have any example for help me ?
Most Valuable Expert 2012
Top Expert 2008

Have you used Reflector, or any other IL Disassembler (ILSpy, JustDecompile, ...)?  They can show you a lot about the .NET framework, and any other .NET assembly that is not obfuscated.

The FileSystemWatcher will generate multiple messages for the same file.  You should implement some type of system that ignores multiple messages.  I have used a hashtable (or Dictionary), to keep track of unique file name instances.

I came up with this output using Reflector:

Output for XmlDocument:

Public Class XmlDocument
    Inherits XmlNode

Output for XmlNode:

<DefaultMember("Item"), DebuggerDisplay("{debuggerDisplayProxy}")> _
Public MustInherit Class XmlNode
    Implements ICloneable, IEnumerable, IXPathNavigable

Output for FileStream:

<ComVisible(True)> _
Public Class FileStream
    Inherits Stream
    ' Methods

Output for Stream:

<Serializable, ComVisible(True)> _
Public MustInherit Class Stream
    Inherits MarshalByRefObject
    Implements IDisposable


Public Sub Dispose()
End Sub


I detect that problem is with the XMLDocument
Most Valuable Expert 2012
Top Expert 2008

It looks like you are loading the XmlDocument from a stream:


You just need to make sure that the stream gets closed.


The dipose don't will stop the programm  with the Me.close?, because I need to create this application in a service.
Most Valuable Expert 2012
Top Expert 2008

From what I showed you before with Reflector output, XmlDocument doesn't implement IDisposable.

The XmlDocument.Load(stream) method does close the stream, though.

Public Overridable Sub Load(ByVal inStream As Stream)
    Dim reader As XmlTextReader = Me.SetupReader(New XmlTextReader(inStream, Me.NameTable))
    End Try
End Sub

Open in new window


Are you suggest that use the XMLTextReader instead XMLDocument ?
Most Valuable Expert 2012
Top Expert 2008

I wasn't suggesting anything, just explaining...

What framework version are you targeting?

If you have 3.5 or higher, I would suggest looking at the XDocument, which uses LINQ-to-XML, which is significantly better than XmlDocument.


I have 3.0

ok I understand I will investigate the Linq to XML do you have any links to consulte it ?

Thanks a lot
Most Valuable Expert 2012
Top Expert 2008
There are a lot of references for LINQ-to-XML, so let's just get started with an example:

XDocument.Parse Method

The XDocument.Parse method is shared (static), and doesn't require an instance variable.  It takes a single string argument (file text).

Dim str As String = _
    "<?xml version= '1.0'?>" & _
    "<!-- comment at the root level -->" & _
    "<Root>" & _
    "  <Child>Content</Child>" & _

Dim doc As XDocument = XDocument.Parse(str)

Open in new window

You can use the System.IO.File.ReadAllText(fileName) method to read the string, and then pass it into the Parse method call.



Thanks to Help Me.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial