C# 使用会话是线程安全的吗?
假设一个用户同时发出多个请求,我是否必须锁定与会话一起工作的所有代码 例如,如果我有以下场景,用户在浏览器的一个选项卡中打开一个页面,然后在第二个选项卡中注销 请求1:C# 使用会话是线程安全的吗?,c#,asp.net,session,thread-safety,C#,Asp.net,Session,Thread Safety,假设一个用户同时发出多个请求,我是否必须锁定与会话一起工作的所有代码 例如,如果我有以下场景,用户在浏览器的一个选项卡中打开一个页面,然后在第二个选项卡中注销 请求1: if(Session["user"] != null) lblName.Text = Session["user"].Name; 请求2: if(logout) Session["user"] = null; 在访问Name属性时,请求1是否可能引发NullPointerException?我是否需要锁定请求1
if(Session["user"] != null)
lblName.Text = Session["user"].Name;
请求2:
if(logout)
Session["user"] = null;
在访问Name属性时,请求1是否可能引发NullPointerException?我是否需要锁定请求1中的代码,以确保用户在检查null后仍然存在?或者ASP.NET会自动处理这个问题吗?是的,会话是线程安全的 没有必要锁定任何东西。然而,检查值的必要性从未停止 更新 检查@Peter Ruderman的答案:)
我有礼貌地不复制它:)一如既往,答案取决于“安全”的含义。在ASP.NET中,每个请求都可以独占访问其会话状态。这意味着您不必担心在单个请求的范围内同步访问。如果会话[“用户”]为非空,则在当前请求的整个持续时间内它将为非空。在您的示例中,请求1永远不会引发空引用异常。在ASP.NET中,请求1将具有一致的读取,请求2将阻止,直到请求1完成。针对同一会话向ASP.NET应用程序发出两个请求,如果处理程序不使用标记接口或未为页面打开标记接口,则ASP.NET运行时将对其进行序列化,以确保状态的一致性。因此,如果您有两个能够写入会话状态的页面,那么无论客户端在它们这方面做什么,它们都将被串行访问
页面/处理程序是否要写入会话状态,取决于应用程序代码使用上述技术向ASP.NET发出信号。如果不这样做,所有请求都将被序列化,web应用程序的性能将受到影响。我猜我的问题标题是错误的,可能是“正在使用会话线程安全”之类的内容。然后,您应该更新您的问题,因为这将更改答案。好的,现在更新了。我仍然不认为这个标题是完美的,但比以前好了那么我们需要检查什么?我会传递一个推荐人,对吗?如果Request2调用会话[“用户”].Dispose(),该怎么办?这会影响我在Request1中从会话中得到的用户吗?是的,在这种情况下,您可能使用了disposed对象。Peter Ruderman的回答说,在Request1中它不能为null。两种观点-什么是正确的?@atticae:这取决于您使用的是内存还是基于SQL的会话状态。在任何情况下,您都应该假设对象可以在多个线程之间共享,并适当地同步访问。@Darryl Braaten:请求1中没有竞争条件,因为ASP.NET在会话中使用读写器锁。请阅读谢谢,这正是我想知道的。不过,这与Darryl Braaten在上述评论中所写的内容相矛盾。那么谁是对的呢?:)这并不完全正确-在默认的InProc模式下,ASP.NET不会复制会话状态;它使用读写器锁来防止不可重复的读取。这意味着请求2将阻塞,直到请求1完成,因为请求1持有此会话的读卡器锁。效果是一样的,但机制是完全不同的。是的,图片比我上面描述的要复杂得多,但关键是你不必同步访问。根据请求是否标记为需要会话状态,您将获得独占访问或独占副本。好吧,哇,我从没想过会话是如此复杂的主题。我在这里学到了很多,谢谢大家。在ASP.Net核心中也是这样吗?我看到的是DistributedSession实现(默认情况下是实例化的),没有任何序列化技术的痕迹,比如locks.。@g.pickardou是否认为Asp.net上的安全威胁仍然适用于Asp.net核心?从同一浏览器上的不同并发请求读取和写入会话上的同一密钥时,我遇到并发问题