我在Web服务中使用Session变量来维护名为QBWC的外部应用程序在连续方法调用之间的状态。我通过使用以下属性修饰我的Web服务方法来设置它:
[WebMethod(EnableSession = true)]
我正在使用Session变量来存储名为QueueManager的自定义对象的实例。 QueueManager有一个名为ChangeQueue的属性,如下所示:
[Serializable]
public class QueueManager
{
...
public Queue<QBChange> ChangeQueue { get; set; }
...
其中QBChange是属于我的Web服务的自定义业务对象。
现在,每当我调用Web服务中的方法时,我都会使用此代码来检索我的QueueManager对象并访问我的队列:
QueueManager qm = (QueueManager)Session[ticket];
然后我使用
从队列中删除一个对象qm.dequeue()
然后我将修改后的查询管理器对象(已修改,因为它包含队列中的少一个对象)保存回Session变量,如下所示:
Session[ticket] = qm;
使用相同的故障单为下一个Web服务方法调用做好准备。
现在就是这样:如果我注释掉最后一行
//Session[ticket] = qm;
,然后Web服务的行为方式完全相同,减少了方法调用之间队列的大小。那为什么呢?
Web服务似乎正在更新Session序列中包含的类,而不会被要求。为什么会这样做?当我反序列化我的Queuemanager对象时,qm变量是否在Session [ticket]变量中保存对序列化对象的引用?这似乎不太可能。
答案 0 :(得分:0)
所有引用类型(例如类)都作为引用存储在内存中,并且会话状态也(通常)存储在内存中,但也可以存储到文件或数据库中。在Session中存储引用类型时,您几乎应该始终确保它们也是Serializable。
QueueManager
是一种引用类型,因此Session[ticket]
所做的就是在内存中保存对它的引用。您无需重新分配,因为Session
变量本身 IS 您正在修改的项目。
这只是您正在做的事情的简化版本:
Session["Foo"] = new Bar();
Bar rar = (Bar)Session["Foo"];
rar.Count = 1;
if (((Bar)Session["Foo"]).Count == 1)
{
// Great success!
}