I have following code to read a file
StreamReader str = new StreamReader(File.Open(fileName, FileMode.Open, FileAccess.Read));
string fichier = str.ReadToEnd();
str.Close();
This is part of a asp.net webservice and has been working fine for an year now in production. Now with increasing load on server, customer has started getting “File already in use” error. That file is being read from this code and is never written to from application.
One problem that I clearly see is that we are not caching the contents of file for future use. We will do that. But I need to understand why and how we are getting this issue.
Is it because of multiple threads trying to read the file? I read that StreamReader is not thread safe but why should it be a problem when I am opening file in Read mode?
You need to open the file with read access allowed. Use this overload of
File.Opento specify a file sharing mode. You can useFileShare.Readto allow read access to this file.Anothr possible solution is to load this file once into memory in a static constructor of a class and then store the contents in a static read-only variable. Since a static constructor is guaranteed to run only once and is thread-safe, you don’t have to do anything special to make it work.
If you never change the contents in memory, you won’t even need to lock when you access the data. If you do change the contents, you need to first clone this data every time when you’re about to change it but then again, you don’t need a lock for the clone operation since your actual original data never changes.
For example:
This encapsulates your data and gives you read-only access to it.
You only need
String.Copy()if your code may modify the file contents – this is just a precaution to force creating a new string instance to protect the original string. Sincestringis immutable, this is only necessary if your code uses string pointers – I only added this bit because I ran into an issue with a similar variable in my own code just last week where I used pointers to cached data. 🙂