2014-11-15 2 views
3

У меня есть службы WCF, обнажая ServiceContract с BasicHttpBinding, поэтому от моего понимания InstanceContextMode будет установлен PerCall (как BasicHttpBinding не поддерживает сеансов) и ConcurrenyMode будет установлен на Покадровый.PerCall InstanceContextMode поведение службы WCF

Клиент этого WCF является службой Windows, которая одновременно вызывает 4 различных операции над сервисом, в рамках службы мы использовали одноэлементный класс, и имеется несколько статических переменных. Мы столкнулись с проблемой, когда неправильное значение передается некоторым хранимым процедурам БД.

С Percall InstanceContextMode и Single concurrency mode я понимаю, что новая служба instacne создана для каждого вызова, и поэтому я думаю, что даже если есть несколько одноэлементных классов (мы не сделали их потокобезопасными) в реализации сервиса и статические переменные все объекты будут уничтожены, но мы наблюдаем запуск профилировщика SQL, который по старому значению получает переданный БД.

Мы написали наш код службы WCF в виде трехуровневой архитектуры, я имею в виду ServiceClass, BusinessLogicLayer и DataAccessLayer, причем PerCall устанавливается как экземплярContextMode, когда мы говорим, что экземпляр службы уничтожается после завершения запроса клиента. означает, что мы уничтожаем весь объект в ServiceClass, BusinessLogicLayer и DataAccessLayer?

Pls помочь мне понять, что может быть пойдет не так

+1

Есть ли причина, по которой вы используете одиночные игры? Это кажется крайне неудовлетворительным шаблоном в вашей архитектуре. Без синглтонов и использования некоторой надлежащей отладки вы должны быть в порядке. – nvoigt

ответ

0

InstanceContextMode PerCall означает новый класс вашей службы конкретизируется за вызов. Статические переменные в вашем AppDomain не будут сброшены. Они будут оставаться между служебными вызовами, пока ваш AppPool не будет переработан.

Удалите все статики, включая одиночные игры из вашего кода. В любом случае, они никогда не принадлежали вашей архитектуре.

+0

Спасибо @nvoigt, что помогло мне лучше понять, есть ли какой-нибудь инструмент, который я имею в виду какой-то инструмент для профилирования памяти, чтобы понять/визуализировать, какие объекты находятся в памяти, какие объекты отсутствуют во время и после вызова службы. – CSharped

+0

@CSharped. Вы можете попробовать некоторые из профайлеры упоминали [здесь] (http://stackoverflow.com/questions/3927/what-are-some-good-net-profilers). – nvoigt

0

Многие запросы WCF используют один и тот же AppDomain. Статические переменные относятся к AppDomain. WCF ничего не делает для этих переменных (фактически он даже не может узнать, что они существуют). Вы несете ответственность за их поддержание.

WCF не уничтожает ни один из ваших объектов, так как и WCF не понимают, что они означают и не знают, что они существуют.

Указанные вами настройки относятся только к объекту службы.

Мой обычный совет относительно приложений с поддержкой состояния сервера: здесь вы работаете с плохой практикой. Вам необходимо обеспечить безопасность потока. В случае отключения рабочего процесса (развертывание, автоматический перезапуск, перезагрузка сервера, ошибка приложения, сбой процесса, потеря мощности, отказ оборудования, ...) ваши данные теряются.

+0

Спасибо @usr, что помогло мне лучше понять, есть ли какой-либо инструмент, который я имею в виду какой-то инструмент профилирования памяти, чтобы понять/визуализировать, какие объекты находятся в памяти, какие объекты отсутствуют во время и после вызова службы. – CSharped

+0

Я считаю, что профайлер памяти Jetbrains имеет инструмент отображения моментальных снимков. Но он не покажет вам объекты, которые живы, но несуществующие (расположены, неправильно сконфигурированы, ...). Я считаю, что ручной осмотр - это путь сюда. Аудит всех статических переменных. – usr

0

Хотя он каким-либо образом ограничен, статические переменные должны быть защищены для обеспечения безопасности потоков в качестве наилучшей практики. Статические переменные не будут уничтожены до тех пор, пока служба не будет остановлена ​​/ перезагрузка приложения.

Использование статических переменных для данных, изменения которых не рекомендуются для распределенных веб-ферм, поскольку они не являются более безопасными при отказе.

Visual Studio 2012 и выше поставляется с профилировщиком памяти. Но простую вещь можно сделать, используя счетчик в конструкторах объектов (только при тестировании), который может определить, есть ли новый экземпляр, созданный по каждому запросу или нет.

[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,ConcurrencyMode=ConcurrencyMode.Single)] 
public class TestServiceWithStaticVars : ITestServiceWithStaticVars 
{ 
    static int instanceCount = 0; 
    public TestServiceWithStaticVars() 
    { 
     Interlocked.Decrement(ref instanceCount); 
    } 
    public string GetInstanceCount() 
    { 
     return string.Format("You have created {0} instance", instanceCount); 
    } 

Сообщите вам, если лучший счетчик экземпляров доступен для использования с легкостью.

[Изменить], поскольку я не могу комментировать сейчас.

Повторное присвоение статической переменной примет новое значение, как вы сказали. Статические переменные загружаются в HighFrequencyHeap для частого доступа. Для получения дополнительной информации http://www.codeproject.com/Articles/15269/Static-Keyword-Demystified

+0

Спасибо, в моем случае у меня есть статическая переменная, вызывающая все проблемы, и теперь я понимаю, что будет храниться в AppDomain соответствующей службы, если мой код повторно инициализирует статическую переменную, переменная примет новое значение? Можете ли вы помочь мне понять, как это работает – CSharped

Смежные вопросы