我有一个问题,希望你能帮帮我,谢谢你。
我正在一个项目中工作,一个在IIS中托管的WEB应用程序;方法是我有一个LogIn用户,但LogIn必须允许一个用户在时间登录,所以如果两个用户同时尝试访问该站点,则只有一个应该访问,而另一个用户等待,直到首先登录。我想到了使用线程,在登录验证中使用了锁定语句,但我不知道在这种情况下使用线程是否是一个好习惯,因为多个用户可能会尝试登录同时,只有一个人必须及时访问。此外,我需要按照用户访问网站的顺序记录用户,以验证两个用户是否同时无法访问。
多线程是一个很好的做法或推荐吗? 有什么建议?非常感谢。
答案 0 :(得分:0)
首先,当使用线程时,这是一种很好的做法,以避免任何阻塞线程的事情,如果可能的话。
你可以使用一个锁,它会导致传入的线程阻塞,直到第一个线程完成登录过程,虽然我看不出这有助于理解多线程。这只会有助于学习如何阻止线程,你应该不惜一切代价避免线程,线程很昂贵。
恕我直言,你应该永远不会拥有比CPU内核更多的线程,使用线程池,了解计算绑定和I \ O绑定线程之间的区别。我再次说线程在时间和内存方面都很昂贵。
答案 1 :(得分:0)
嗯,这个解决方案不是关于多线程 - 但我会这样做:
public class SingleUserLock : IDisposable
{
private SingleUserSemaphore _parent;
public SingleUserLock(SingleUserSemaphore parent)
{
_parent = parent;
}
public bool IsLoggedIn => _parent?.CurrentUser == this;
public void Unlock()
{
_parent?.Unlock();
_parent = null;
}
public void Dispose()
{
Unlock();
}
}
public class SingleUserSemaphore
{
private readonly object _lockObject = new object();
public SingleUserLock CurrentUser { get; private set; }
public bool TryLogin()
{
if (Monitor.TryEnter(_lockObject))
{
CurrentUser = new SingleUserLock(this);
return true;
}
return false;
}
public void Unlock()
{
try
{
Monitor.Exit(_lockObject);
CurrentUser = null;
}
catch (Exception ex) { };
}
}
在DependecyInjection框架中为Web应用程序注册SingleUserSemaphore实例作为Singleton。每次用户登录时,您都会获得单例SingleUserSemaphore实例并调用TryLogin。如果为true,则可以在会话中存储SingleUserLock(如果可能)。
对于每个请求,请检查IsLoggedIn == true
的会话。
当用户退出时,您可以从会话中调用返回的SingleUserLock.Unlock();
或直接SingleUserSemaphore.Unlock();
现在挑战将是,如果用户永远不会退出。您的Web应用程序将永久锁定。为避免这种情况,您可以在SingleUserSemaphore
上使用时间戳为登录用户发出的每个请求创建一个Update方法。因此,当用户登录时,您还会检查上一个活动...
祝你好运。