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..