2009-08-14 6 views
4

У меня есть служба Windows на C#. Он функционирует и работает хорошо. Я добавил службу WCF службе Windows, чтобы клиентские приложения могли подключаться к службе Windows и получать информацию о состоянии с помощью службы Windows.Как настроить WCF ServiceHost в службе Windows, которая может получить доступ к информации о состоянии в службе Windows

Я настроил службу WCF, чтобы быть одноточечны, так что тот же экземпляр службы используется для обработки всех запросов от всех клиентов следующим образом:
[ServiceBehavior (InstanceContextMode = InstanceContextMode.Single)]

Всех клиентов могут подключаться и иметь доступ к одной и той же информации о состоянии в службе WCF. Однако я сталкиваюсь с следующим своеобразным поведением.

После доработки:
Я экземпляр контракта службы WCF внутри моей службы Windows. Любая информация о состоянии, назначенная во время создания экземпляра, доступна всем клиентам, которые подключаются к службе.

Тем не менее, любая информация о состоянии, добавленная к договору на обслуживание экземпляра позже непосредственно из службы Windows (а не клиентами) не отображается клиентам, которые подключаются к службе. Это похоже на два варианта контракта на обслуживание: один для службы Windows и один для клиентов, которые подключаются к службе WCF.

Каков рекомендуемый (лучший) способ создания экземпляра службы WCF и иметь возможность доступа к информации о состоянии, доступной в службе Windows?

ответ

2

Я бы порекомендовал бы сделать это в конце, удерживая свое состояние в статическом члене, так что не имеет значения, создает ли WCF новый экземпляр для каждого вызова или его повторное использование. Это решает проблему и упрощает код.

2

Почему служба WCF должна иметь информацию о состоянии состояния? Не удалось ли сохранить его в базе данных и получить доступ, когда это необходимо?

WCF разрешает экземпляры Singleton для служб - но обычно это не рекомендуется использовать, если только вы абсолютно не должны это делать. Как правило, это проще и масштабируется намного лучше, если вы можете хранить информацию о состоянии, например. таблицу базы данных и позволить клиентам получить доступ к ней с использованием обычной службы WCF для каждого вызова.

UPDATE:
ОК, еще одна идея: вы всегда будете только буду иметь один ServiceHost в любом случае. Если вы выбираете режим instanciation для каждого вызова (как рекомендовано всеми ведущими экспертами), ServiceHost будет выделять пул потоков рабочих потоков, который затем будет обслуживать входящие запросы.

Почему служба WCF должна быть одиночной? Не могли бы вы использовать «за звонок» и все еще получать информацию о состоянии в службе NT?

Выполняется запрос, и создается экземпляр объекта службы (класс обслуживания, реализующий интерфейс службы). Как вы получаете доступ к информации о состоянии в службе NT прямо сейчас? Не могли бы вы сделать это и из вновь созданного экземпляра службы - когда вам это действительно нужно?

Если у вас есть информация о состоянии, хранящаяся в службе NT, вам необходимо убедиться, что любой параллельный доступ будет обработан надлежащим образом - это абсолютно не зависит от того, является ли ваш класс службы WCF одиночным или нет.

UPDATE 2:
Используя «OperationContext.Current.Host», вы можете получить доступ к ServiceHost, на котором размещен данный экземпляр службы внутри метода службы выполняется - не уверен, если вы можете получить доступ к фактическому экземпляру службы NT , Но если вы создадите свой собственный пользовательский потомок ServiceHost с дополнительным свойством «ListOfClients», вы сможете получить доступ к этому списку в любой момент из любого экземпляра службы.

УМ ВАС:, поскольку там, возможно, любое количество запросов на обслуживание обрабатываемого в любой момент времени, читая список должны быть поточно-и обновлением списка из службы Windows NT еще более «рискованный» и необходимо учитывать эти проблемы параллелизма! Заблокируйте список, если вам нужно его обновить, иначе вы получите непредсказуемые результаты.

Марк

+0

Я действительно не нужна услуга WCF, чтобы быть с сохранением состояния. У меня есть информация о состоянии уже в службе Windows. Именно эта информация я хочу, чтобы служба WCF могла предоставлять клиентам, которые ее запрашивают. Как я могу это решить? – Elan

+0

Конечно, я мог бы решить это, сохранив информацию в базе данных. Это просто лишние накладные расходы, когда информация уже доступна в службе Windows, особенно когда служба WCF размещается в контексте службы Windows. Кажется, мне не следует теперь дополнительно хранить его и извлекать из базы данных, чтобы сделать его доступным для клиентов. В идеале я хотел бы, чтобы служба WCF предоставляла доступ к данным с состоянием в службе Windows. – Elan

+0

Чтобы ответить на ваш вопрос, я изначально начал назначать ссылку на список экземпляру хоста службы WCF, но теперь уйдет от этого подхода, поскольку он не работает, кроме требования Singleton. – Elan

1

Установка InstanceContextMode.Single заставит ServiceHost построить один экземпляр сервиса и использовать его для всех вызовов. Но похоже, что вы хотели бы построить экземпляр самостоятельно и заполнить его ссылкой на какое-то общее состояние. Если да, то, что называется «хорошо известный случай» модели и может быть достигнуто путем передачи экземпляра к ServiceHost constructory, например, так:

var svc = new MyServiceClass(state); 
var host = new ServiceHost(svc, new Uri(..), ...); 
... 

ServiceHost будет использовать экземпляр, который пройдет в течение всех вызовов.

Важное соображение при использовании режима Single instance (независимо от того, является ли объект «общеизвестным» или сконструирован ServiceHost) является потоковым. По умолчанию WCF разрешает только один поток выполнять одновременно за экземпляр службы. Поэтому в режиме экземпляра PerCall, поскольку у вас будет несколько экземпляров службы, вы можете поддерживать несколько одновременных потоков, что улучшит пропускную способность при нормальных условиях. Но в режиме Single instance у вас есть только один экземпляр службы, поэтому вы будете запускать только один поток за раз. Это зависит от службы, но часто имеет смысл переключить режим параллелизма на Multiple, что позволит использовать несколько параллельных потоков в вашем экземпляре службы, но требует, чтобы ваша реализация сервиса была потокобезопасной.

Некоторые хорошие документы здесь: http://msdn.microsoft.com/en-us/library/ms731193.aspx