I/O handles can't be released

G

Guest

I have a window service written in VB.NET to scan directory and process file.
During directory scanning (scheduled by timer using
System.IO.Directory.GetFiles method), I can observe that the column "Handles"
in "Task Manager" will increase gradually but will be dropped after a short
while.

But when CPU is busy (reach 100%), the number specified by "Handles"
increases continuously until I have to manually stop the window service or
the server will be run out of resources. During this period of time, the "VM
Size" increases faster than "Mem Usage". Some readings of the window service
I grabbed from "Task Manager" are shown as follows:

CPU - 40%
Mem Usage - 66, 180K
VM Size - 175, 380K
Handles - 190, 172
Thread - 62

Any idea why the I/O handles cannot be released but instead grows
continually and tremendously?
Directory.GetFiles method will tentatively cause this problem?
Why the VM Size is increased faster than Mem Usage in this case?
What workaround can be added to my code to handle the problem?

Thanks
 
K

Ken Tucker [MVP]

Hi,

The garbage collector hasnt taken out the garbage. Make sure you
dispose of any unused variables. Call gc.collect to force the framework to
take out the garbage.

Ken
-------------------
I have a window service written in VB.NET to scan directory and process
file.
During directory scanning (scheduled by timer using
System.IO.Directory.GetFiles method), I can observe that the column
"Handles"
in "Task Manager" will increase gradually but will be dropped after a short
while.

But when CPU is busy (reach 100%), the number specified by "Handles"
increases continuously until I have to manually stop the window service or
the server will be run out of resources. During this period of time, the "VM
Size" increases faster than "Mem Usage". Some readings of the window service
I grabbed from "Task Manager" are shown as follows:

CPU - 40%
Mem Usage - 66, 180K
VM Size - 175, 380K
Handles - 190, 172
Thread - 62

Any idea why the I/O handles cannot be released but instead grows
continually and tremendously?
Directory.GetFiles method will tentatively cause this problem?
Why the VM Size is increased faster than Mem Usage in this case?
What workaround can be added to my code to handle the problem?

Thanks
 
G

Guest

Thanks for the reply

I have a timer which elapses every minute and it will call GC.Collect to
execute. But seem this has no effect to release the I/O handles and memory.

My code on directory scanning like this:

-----------------------------------------------------------------------------------------------
Dim fileEntries As String() = Directory.GetFiles(targetDir)
Dim fileEntry As String
Dim DateTime As String
Dim FileName As String
Dim alFileName As New ArrayList()

'**************************************************
' Process the list of files found in the directory
'**************************************************
For Each fileEntry In fileEntries
Dim fi As New FileInfo(fileEntry)
' Format File CreationTime
DateTime = Format(Directory.GetCreationTime(fileEntry), "dd/MM/yyyy
hh:mm:ss fffffff")

' The file is txt file
If fi.Extension.CompareTo(".txt") = 0 Then
' If not yet added in ArrayList, add [DateTime & File Path]
If Not alFileName.Contains(DateTime & ";" & fileEntry.ToString) Then
alFileName.Add(DateTime & ";" & fileEntry.ToString)
End If

txtFound = True

' File is OTHER than txt Extension, Move to ERROR folder ***
ElseIf fi.Extension.CompareTo(".txt") <> 0 Then
If (File.Exists(fileEntry)) Then
cf.MoveFile(fileEntry.ToString, Mid(fileEntry,
fileEntry.LastIndexOf("\") + 2), "Error", 0, type)
End If
End If
fi = Nothing
Nex
------------------------------------------------------------------------------------------------

How to force the I/O handles to release? Or can I add code to force I/O
handles to release after its attempt to get files is failed within a
predefined time?

Seem that the I/O handles keep on increase because my timer elapsed event is
continuously trigger the directory scanning action. With the previous I/O
handles still try to scan the directory (CPU busy has caused the delay to the
directory scanning [correct me if I'm wrong]), the I/O handles will be
increased and lead to memory leak. How am I suppose to do to control for this?
 
L

Larry Serflaten

LBT said:
For Each fileEntry In fileEntries
Dim fi As New FileInfo(fileEntry)


Because you are creating a new object for each iteration:

The first question I would ask is; why are you using methods of
the FileInfo class, instead of static methods of the File class?

LFS
 
G

Guest

Last time I just get the idea from somewhere else.

If FileInfo is not suitable to be used for my case, may I know the
workaround using File Class? What is the benefit of using static methods vs
instance methods (FileInfo class) for my case? FileInfo class will
potentially cause more and more I/O handled to be created and never be
released when CPU is busy? Would appreciated if some URLs of reference are
given :)
 
L

Larry Serflaten

LBT said:
Last time I just get the idea from somewhere else.

If FileInfo is not suitable to be used for my case, may I know the
workaround using File Class?


I got pointed to the File class from the documentation on the FileInfo
class. Really what you'd use is the Path.GetExtension function. That
would return the extension for you to make your comparisons. It
also will avoid creating a new object for every iteration. Why make
the GC work, when you can (easily) avoid it?

HTH
LFS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top