Threading Results in FileOpen conflict

Posted on 2014-01-16
Last Modified: 2014-01-16
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?
Question by:lep1
  • 2
LVL 40

Accepted Solution

Jacques Bourgeois (James Burger) earned 500 total points
ID: 39785429
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

Author Closing Comment

ID: 39785500
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

LVL 40
ID: 39785870
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

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IP addresses can be stored in a database in any of several ways.  These ways may vary based on the volume of the data.  I was dealing with quite a large amount of data for user authentication purpose, and needed a way to minimize the storage.   …
The object model of .Net can be overwhelming at times – so overwhelming that quite trivial tasks often take hours of research. In this case, the task at hand was to populate the datagrid from SQL Server database in Visual Studio 2008 Windows applica…
In a recent question ( here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

860 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question