假设我有一个服务需要登录才能访问它。有一个功能:
void Login(LoginInfo info);
它实现了服务的登录逻辑。还有一个功能:
void RequestServiceToDoSomething(RequestInfo info);
Login 函数发送凭据并检索随后由每个 RequestServiceToDoSomething 使用的 SessionId。如果由于某种原因 SessionId 变得无效,则 RequestServiceToDoSomething 会引发异常。
当您必须处理一个单线程时,这非常简单。当多个线程想要使用相同的 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% 正确,但您明白了。