KnowDotNet

Visual Studio .NET Tips and Tricks

Using .NET Framework Classes Wisely

by Les Smith

Whether you develop in VB.NET or C#, this article describes a little coding tip to keep you out of trouble.  The .NET Framework has given us some wonderful new tools that we used to have to get along without before .NET.  But, you must be careful how you use them.

For example, I have had to assume responsibility for some applications for a developer who is no longer with the company where I currently have a contract. He had several bad habits, from which none of us is exempt. One of his that constantly bugs me is the way that he used the Directory.GetFiles.  Don't get me wrong, I use it but there is a subtle difference in the way that I use it that keeps me out of trouble, actually an infinite loop.

Here is a typical example of the way that he used it.

     Dim files() As FileInfo = dir.GetFiles
    
For Each f As FileInfo In dir.GetFiles
        
' do processing of the file here...
         ProcessFile(f.FullName)

        
' archive the file as a unique name
         IO.File.Move(Path.Combine(inputWorkDir, f.Name), _
            Path.Combine(inputArchiveDir, _
            Path.GetFileName(f.FullName) & "_" & Format(Now, "yyyyMMddHHmmss")))
      
Next

There are at least two problems with the code snippet shown above.  First, there is no exception handler for the Move method call.  However, if we encapsulate the code in a Try/Catch block, we will still have a problem if the file does not get moved.  Each time the For Each is executed, a new call to dir.GetFiles is made.  If the processed file does not get moved, it will be the first file picked up and sent to ProcessFile again.  If that does cause any problem, other than that we processed the same file, we will be in an infinite loop processing the same file over and over.

Having recognized this potential disaster in all of his applications, I always change the code just slightly to eliminate the problem.  that code is shown below.  I am using the same Framework methods, but in a slightly different way.  First, I dimension an array of FileInfo objects and then loop thru it.  That way, if a file does not get moved, I will not see it again, and therefore will not process it again.  That solution is shown below.


      Dim files() As FileInfo = dir.GetFiles
      
For Each f As FileInfo In files
        
' do processing of the file here...
         ProcessFile(f.FullName)

        
' archive the file as a unique name
         IO.File.Move(Path.Combine(inputWorkDir, f.Name), _
            Path.Combine(inputArchiveDir, _
            Path.GetFileName(f.FullName) & "_" & _
            Format(Now, "yyyyMMddHHmmss")))

      
Next

This is a subtle change, but it is nonetheless significant.  Now, I realize that this code needs to be  enhanced to take action when the file move fails, otherwise it will still be in he inputWorkDir the next time we process, but that's another subject, which I will not persue in this article.

This is another of my articles that does not take a rocket scientist to figure out, but it is a subtle trap that the former employee fell into everytime he looped through a directory of files.  Hopefully, it never caused a problem, but it does, the results could be nasty and needlessly.

If you have any comments or suggestions on this article or any other programming subject you would like to discuss, comment on my blog at Click Here.