アクセスするためにログに記録する必要のあるサービスがあると仮定します。機能があります:
void Login(LoginInfo info);
これは、サービスへのログインロジックを実装します。そして、機能があります:
void RequestServiceToDoSomething(RequestInfo info);
Login関数は、資格情報を送信し、その後すべてのRequestServiceToDoSomethingによって使用されるSessionIdを取得します。何らかの理由でSessionIdが無効になった場合、RequestServiceToDoSomethingは例外をスローします。
1つのスレッドを処理する必要がある場合、これは非常に簡単です。複数のスレッドが同じSessionIdを使用してリクエストを実行したい場合に問題が発生します。
これまでの問題への私のアプローチはこれです:
class Foo {
...
private object SessionId;
private DateTime LastSuccessfullLogin;
private const int LoginValidPeriod = 5;
...
public void Login(LoginInfo)
{
lock (LastSuccessfullLogin) {
if ((DateTime.Now - LastSuccessfullLogin).Seconds < LoginValidPeriod)
return;
}
lock (Logging) {
if (Logging == true)
return;
else
Logging = true;
AquireWriteLock();
}
try {
// DO STUFF THAT UPDATE SessionId
lock (LastSuccessfullLogin) {
LastSuccessfullLogin = DateTime.Now;
}
}
finally {
lock (Logging) {
Logging = false;
}
ReleaseWriteLock();
}
}
...
void RequestServiceToDoSomething(RequestInfo info) {
try {
AquiareReadLock();
// DO REQUEST BASED ON SessionId
}
finally {
ReleaseWriteLock();
}
}
私の問題は、LastSuccessfullLoginチェックが必要かどうか、そしてこのパターンが不要なログイン実行を防ぐかどうかです。より効率的でわかりやすいパターンはありますか?
PS提供されたコードは、文法的にも構文的にも100%正しいわけではありませんが、理解できます。