непредвиденное поведение объекта, сохраненного в сеансе веб-службы - PullRequest
1 голос
/ 07 мая 2010

Я использую переменные Session внутри веб-службы для поддержания состояния между последовательными вызовами методов внешним приложением под названием QBWC.Я настроил это, украсив методы моего веб-сервиса этим атрибутом:

[WebMethod(EnableSession = true)]

Я использую переменную Session для хранения экземпляра пользовательского объекта с именем QueueManager.QueueManager имеет свойство ChangeQueue, которое выглядит следующим образом:

 [Serializable]
 public class QueueManager
 {
  ...
  public Queue<QBChange> ChangeQueue { get; set; }
  ...

, где QBChange - это настраиваемый бизнес-объект, принадлежащий моему веб-сервису.

Теперь каждый раз, когда я получаю вызовметод в моем веб-сервисе, я использую этот код для извлечения моего объекта QueueManager и доступа к своей очереди:

QueueManager qm = (QueueManager)Session[ticket];

, затем я удаляю объект из очереди, используя

qm.dequeue()

, а затемЯ сохраняю измененный объект диспетчера запросов (измененный, поскольку он содержит на один объект меньше в очереди) обратно в переменную Session, например, так:

Session[ticket] = qm; 

готов к следующему вызову метода веб-службы с использованием того же билета.

Теперь вот что: если я закомментирую эту последнюю строку

//Session[ticket] = qm;

, то веб-служба будет вести себя точно так же, уменьшая размер очереди между вызовами методов.Теперь, почему это?

Кажется, что веб-служба обновляет класс, содержащийся в сериализованной форме, в переменной Session без запроса.Зачем это делать?Когда я десериализую свой объект Queuemanager, содержит ли переменная qm ссылку на сериализованный объект внутри переменной Session [ticket] ??Это кажется маловероятным.

1 Ответ

0 голосов
/ 07 мая 2010

Все ссылочные типы (например, классы) хранятся в памяти как ссылки, а Session State также (обычно) хранится в памяти, но также может храниться в файле или базе данных. При хранении ссылочных типов в сеансе вы почти всегда должны убедиться, что они также являются сериализуемыми.

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!
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...