views:

670

answers:

3

I have deployed ASP.NET web site and ASP.NET web service on the same web server. Both of them require access to shared file.

How to implement/share lock that supports single writers and multiple readers? If somebody reads, nobody can write, but all still can read. If somebody writes, nobody can read/write.

+2  A: 

to open file for writing with allowing other threads to read it use System.IO.File.Open method with System.IO.FileShare.Read. Ie.:

System.IO.File.Open("path.txt",System.IO.FileMode.OpenOrCreate,System.IO.FileAccess.ReadWrite,System.IO.FileShare.Read)

Other (reading) threads should use System.IO.FileAccess.Read

Signature of Open method:

public static FileStream Open(string path, FileMode mode, FileAccess access, FileShare share);

UPDATE If you need all instances to ocasionally write to file. Use Mutex class to reserve file writing. Ie.:

    Mutex mut = new Mutex("filename as mutex name");
    mut.WaitOne();
    //open file for write, 
    //write to file
    //close file
    mut.ReleaseMutex();

Hope it helps.

Bartek Szabat
A: 

Well, you can do something like this:

public class yourPage {
    static object writeLock = new object();
    void WriteFile(...) {
         lock(writeLock) {
              var sw = new StreamWriter(...);
              ... write to file ...
         }
}

Basically, this solution is only good for cases when the file will be opened for writing a short amount of time. You may want to consider caching the file for readers, or writing the file to a temp file, then renaming it to minimize contention on it.

Dave Markle
Wouldn't this be irrelevant if two different objects of this class are created each in its own thread? Each of them would get a copy of writeLock, thus making the entire locking scheme useless. I believe that the writeLock should be declared "upstream" before different threads are created, like in the Global.asax file.
Tudor Olariu
@Tudor: If the object is "static", there is only one instance of it per process, not per thread. The variable truly is global to all threads. You can, however, decorate it with a [ThreadStatic] attribute, and it would be just as you describe (useless!)
Dave Markle
+1  A: 

Use the ReaderWriterLock or ReaderWriterLockSlim (.NET 2.0) class from the System.Threading namespace to handle single writer / multiple reader cases.

jezell