How do I make a lock that allows only ONE thread to read from the resource ?

Posted by mare on Stack Overflow See other posts from Stack Overflow or by mare
Published on 2011-06-24T14:46:11Z Indexed on 2011/06/24 16:23 UTC
Read the original article Hit count: 176

Filed under:
|

I have a file that holds an integer ID value. Currently reading the file is protected with ReaderWriterLockSlim as such:

    public int GetId()
    {
        _fileLock.EnterUpgradeableReadLock();
        int id = 0;
        try {
            if(!File.Exists(_filePath))
                CreateIdentityFile();

            FileStream readStream = new FileStream(_filePath, FileMode.Open, FileAccess.Read);
            StreamReader sr = new StreamReader(readStream);
            string line = sr.ReadLine();
            sr.Close();
            readStream.Close();
            id = int.Parse(line);
            return int.Parse(line);
        }
        finally {
            SaveNextId(id);     // increment the id 
            _fileLock.ExitUpgradeableReadLock();
        }
    }

The problem is that subsequent actions after GetId() might fail. As you can see the GetId() method increments the ID every single time, disregarding what happens after it has issued an ID. The issued ID might be left hanging (as said, exceptions might occur). As the ID is incremented, some IDs might be left unused.

So I was thinking of moving the SaveNextId(id) out, remove it (the SaveNextId() actually uses the lock too, except that it's EnterWriteLock). And call it manually from outside after all the required methods have executed. That brings out another problem - multiple threads might enter the GetId() method before the SaveNextId() gets executed and they might all receive the same ID.

I don't want any solutions where I have to alter the IDs after the operation, correcting them in any way because that's not nice and might lead to more problems.

I need a solution where I can somehow callback into the FileIdentityManager (that's the class that handles these IDs) and let the manager know that it can perform the saving of the next ID and then release the read lock on the file containing the ID.

Essentialy I want to replicate the relational databases autoincrement behaviour - if anything goes wrong during row insertion, the ID is not used, it is still available for use but it also never happens that the same ID is issued. Hopefully the question is understandable enough for you to provide some solutions..

© Stack Overflow or respective owner

Related posts about c#

Related posts about .NET