Единственный способ иметь два разных клиента WCF, то есть прокси, ссылающихся на один и тот же экземпляр службы WCF, - это использовать InstanceContextMode=InstanceContextMode.Single
. Это плохой выбор, если масштабирование является проблемой, поэтому вы можете использовать PerCall
, если можете.
При использовании PerCall
, каждый CALL для службы WCF получает свой собственный экземпляр службы WCF . Нет общего доступа к экземпляру службы, но это не означает, что они не используют одно и то же внутреннее хранилище (например, базу данных, память, файл и т. Д.). Просто помните, PerCall
позволяет каждому звонить для одновременного доступа к вашей службе WCF.
Параметр ConcurrencyMode
контролирует модель потоков самой службы. Значение Single
ограничивает запуск всех экземпляров службы WCF в одном потоке. Таким образом, если у вас есть несколько клиентов, подключающихся одновременно, они будут выполняться только по одному на стороне службы WCF. В этом случае вы используете WCF для обеспечения синхронизации. Как вы видели, он будет работать нормально, но думайте об этом как о наличии только макроуровневого контроля над синхронизацией - каждый вызов службы WCF будет выполняться полностью до того, как может быть выполнен следующий вызов.
Установка ConcurrencyMode
на Multiple
, однако, позволит всем экземплярам службы WCF выполняться одновременно. В этом случае вы несете ответственность за обеспечение необходимой синхронизации . Думайте об этом, как о контроле синхронизации на микроуровне, поскольку вы можете синхронизировать только те части каждого вызова, которые должны быть синхронизированы.
Надеюсь, я объяснил это достаточно хорошо, но вот фрагмент документации MSDN для ConcurrencyMode
на всякий случай:
Установка параметра ConcurrencyMode на Single указывает системе на ограничение
экземпляры службы в один поток
исполнения за один раз, что освобождает
Вы имеете дело с потоками
проблемы. Значение Multiple означает, что
сервисные объекты могут быть выполнены
несколько потоков одновременно. В
В этом случае вы должны обеспечить поток
безопасность.
EDIT
Вы спросили
Есть ли какое-либо увеличение производительности при использовании PerCall по сравнению с Single при использовании ConcurrencyMode.Single? Или верно обратное?
Вероятно, это будет зависеть от услуги.
При InstanceContextMode.PerCall
новый экземпляр службы создается для каждого вызова через прокси-сервер, поэтому вам приходится иметь дело с созданием дополнительных экземпляров. Предполагая, что ваш конструктор сервисов мало что делает, это не будет проблемой.
При InstanceContextMode.Single
существует только один экземпляр службы на время существования приложения, поэтому с созданием экземпляра практически не связано никаких накладных расходов. Однако этот режим позволяет только одному экземпляру службы обрабатывать каждый вызов, который когда-либо будет сделан. Таким образом, если вы выполняете несколько вызовов одновременно, каждому вызову придется ждать завершения других вызовов, прежде чем он будет выполнен.
Для чего это стоит, вот как я это сделал. Используйте PerCall
контекстный экземпляр с Multiple
параллелизмом. Внутри вашего класса обслуживания WCF создайте статические элементы для управления внутренним хранилищем данных, а затем синхронизируйте доступ к этим статическим элементам при необходимости с помощью оператора lock
, полей volatile
и т. Д. Это позволяет масштабировать службу. прекрасно, сохраняя при этом безопасность потоков.