我有一個包含整數ID值的文件。目前讀取該文件與ReaderWriterLockSlim
保護這樣:如何製作只允許一個線程從資源讀取的鎖定?
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();
}
}
的問題是,GetId()
後後續行動可能會失敗。正如你所看到的,GetId()
方法每次都會增加ID,不管發出ID後會發生什麼。發佈的ID可能會被掛起(如上所述,可能會發生異常)。隨着ID增加,一些ID可能未被使用。
所以我想移動SaveNextId(id)
,刪除它(SaveNextId()
實際上也使用鎖,除了它是EnterWriteLock
)。在完成所有必需的方法執行後,從外部手動調用它。這帶來了另一個問題 - 在執行SaveNextId()
之前,多個線程可能會輸入GetId()
方法,並且它們可能都會收到相同的ID。
我不希望任何解決方案,在操作後必須更改ID,並以任何方式糾正它們,因爲這樣做不好,可能會導致更多問題。
我需要一個解決方案,我可以以某種方式回調到FileIdentityManager(這是處理這些ID的類),並讓管理員知道它可以執行保存下一個ID然後釋放包含文件的讀鎖定ID。
Essentialy我想複製關係數據庫的自動增量行爲 - 如果在行插入過程中出現任何錯誤,這個ID不被使用,它仍然可以使用,但它也不會發生相同的ID發出。希望這個問題是可以理解的不足,爲您提供一些解決辦法..
UPDATE:請參見注釋給答案有關行爲的詳細信息我想
我認爲你有非順序的ID是一件壞事嗎? – Chris
如果你想要一個只允許一個線程的鎖,爲什麼不使用'lock'?我只是閱讀標題而不是問題! –
我會處理因刪除而發生的問題。但我不想把它們浪費在沒有成功的文件保存上,沒有成功的類型轉換等等。我現在就開始工作了,但這個非序列ID問題很快就顯示出來了,因爲ID暴露在UI中,它看起來很難看。兩個併發內容項目可能具有相隔10個數字或更多的ID。 – mare