Go Premium for a chance to win a PS4. Enter to Win


Threading Results in FileOpen conflict

Posted on 2014-01-16
Medium Priority
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 2000 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

Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

Question has a verified solution.

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

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Simulator games are perfect for generating sample realistic data streams, especially for learning data analysis. It is even useful for demoing offerings such as Azure stream analytics, PowerBI etc.
Integration Management Part 2
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Suggested Courses

972 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