Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 222
  • Last Modified:

Threading Results in FileOpen conflict

If I start a thread for the following subroutine, I will get a fileopen conflict (the file will be in use conflict), otherwise, if I simply call the routine without using a thread there won't be a conflict.   For some reason, it seems that threading causes the loop to get "ahead of itself" such that the file does not close in time?

'Option 1:
Dim t As New Thread(Addressof ProcessFile())
t.start --> causes file in use error


Call Processfile() --> does not cause file access error

Sub Processfile()
  For i As Integer = 1 to 10
     Fileclose(1)   'Close for safety sake
     FileOpen(101, myfile, OpenMode.Input)

          .... Process data

End Sub

Open in new window

Basically, when the thread is used, it seems that the file processing inside the loop is not sequential since the file does not close in time for the next loop increment.   Basically, it appears that the loop is almost done in parallel, such that the value of i=1,2,...,10 is not really followed sequentially.  

Basically, threading seems to override sequential operations in loops?
  • 2
1 Solution
Jacques Bourgeois (James Burger)PresidentCommented:
Do not use the old file system (FileOpen). They were already outdated in VB6 where most programmers were using a TextStream object instead. It's been kept in .NET to ease conversion of old applications and tremendously limit what you can do, as you see in your code. The documentation is very clear about that : The FileClose function is provided for backward compatibility and may affect performance

Learn to use the .NET classes to work with files. It requires losing old habits for somebody who still uses file techniques from the 80's, but it's worth taking the time to familiarize yourself with modern techniques. You will be able to do a lot more, often with less code. You gain nothing by moving to .NET if you keep doing things the old way.

Dim yourFile As New System.IO.StreamReader(myFile)
Dim text As String

text = yourFile.ReadLine
text = yourFile.ReadToEnd
any of the many methods of the class

To write data, you can use a StreamWriter.

If you work with binary data, a BinaryReader and a BinaryWrite will ease the job because they have specific methods to read specific types of binary data.

Since you are creating a New variable for each file, you do not end up with the conflicts that can arise by using numeric file channels. Conflicts will arise only if you try to use the same file with different objects
lep1Author Commented:
Thanks - very helpful.  I agree, if you instantiate the file as a new object (class) then there won't be a conflict.  It will also be more efficient, and get killed during GC.

What command should be used to kill the class object when you are done with IO - maybe

yourFile = nothing

Jacques Bourgeois (James Burger)PresidentCommented:
Things are a lot different in .NET than they were in VB6, even when the syntax is the same.

Setting an object to Nothing in .NET is most often useless and can sometimes lead to problems.

It's useless because unlike VB6, it does not destroy the object, it simply tells the GC that the variable is available for garbage collection. But if you know about the GC, you might have learned that it typically does its job only when the system is low in resources.

In the case of a Stream that references a file, that means that the file is not released until the GC decides to finalize the Stream. This can take hours, even days on a system that goes to sleep.

There is a standard in .NET to release external resources. It's a Dispose method. If you see a class that has a Dispose method, it's good practice to call Dispose when you do not need the object anymore. Although it is not the same things, this is what is the closest to the old variable = Nothing. If a class does not have a Dispose method, that means that it does not hold external resources and the GC will take care of things by itself. An alternative to calling Dispose is to declare the variable with Using instead of Dim. Look it up in the documentation, but make sure that you are in the Visual Basic documentation, because using means something else in C#.

This being said, since programmers were used to Close a form, Close a connection or Close a file, many classes have a Close method that calls Dispose under the hood.

So, for a class that deals with files, most programmers will simply call the Close method to release the file. But some will prefer Dispose. It's up to you. But one important thing. While Close was automatic in VB6, it needs to be called in .NET.

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now