私は、整数のID値を保持するファイルを持っています。問題がGetId()
後に後続のアクションが失敗するかもしれないということです1つのスレッドだけがリソースから読み取ることを許可するロックを作成するにはどうすればよいですか?
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();
}
}
:現在のファイルを読むことなどReaderWriterLockSlim
で保護されています。あなたが見ることができるように、GetId()
メソッドは毎回IDをインクリメントし、IDを発行した後に何が起こるかは無視します。発行されたIDはハングアップする可能性があります(例外が発生する可能性があります)。 IDがインクリメントされると、一部のIDは未使用のままになることがあります。
私はSaveNextId(id)
を取り除くことを考えていましたが、それを削除してください(SaveNextId()
は実際にはロックを使用しますが、それ以外はEnterWriteLock
です)。そして、必要なすべてのメソッドが実行されたら、外部から手動で呼び出します。これにより、SaveNextId()
が実行される前に複数のスレッドがGetId()
メソッドに入り、すべて同じIDを受け取る可能性があるという別の問題が発生します。
私は操作後にIDを変更する必要はありません。何らかの方法でIDを変更する必要はありません。なぜなら、それはうまくいかず、より多くの問題につながる可能性があるからです。
私は何とかFileIdentityManager(これらのIDを処理するクラス)にコールバックでき、次のIDの保存を実行できることをマネージャに知らせるソリューションが必要です。 ID。
要点リレーショナルデータベースの自動インクリメントの動作を複製したい - 行挿入中に何か問題が生じた場合、そのIDは使用されず、引き続き使用できますが、同じIDが発行されることはありません。うまくいけば、問題は
UPDATE ..あなたは、いくつかのソリューションを提供するための十分な理解:私は私がしたい
私は非連続IDを持つことが悪いことだと思いますか? – Chris
一度に1つのスレッドしか許可しないロックを望むなら、 'lock'を使わないのはなぜですか?私はちょうど質問よりむしろタイトルを読んだ! –
私は削除の結果として起こるものと一緒にします。しかし、私は不成功のファイルセーブ、不成功な型キャストなどでそれらを無駄にしたくありません。私はそれを今働いていますが、この問題は素早く表示され、IDがUIに公開されているので醜いです。 2つの並行コンテンツ項目は、10個以上離れたIDを持つことがあります。 – mare