2016-07-09 5 views
2

я не видел это ответил еще, довольно простая настройка ...WCF Вызов службы из службы

Вопрос: Я получаю в тупик, я хочу знать, как избежать этого, учитывая мои настройки ,

У меня есть ServiceA, который реализует IServiceA и ServiceB, который реализует IServiceB. Обе службы отмечены как "perSession" и "Реентрантная" ...

IServiceA поддерживает этот метод:

DataA GetDataA(); 

IServiceB поддерживает этот метод:

DataB GetDataB(); 

в моем приложении, я вызовите метод ServiceA GetDataA() и внутри метода GetDataA ServiceA, он открывает прокси-соединение с ServiceB и вызывает GetDataB().

GetDataB на конце обслуживания (а не на стороне клиента) выполняется правильно (журнал отладки говорит об этом), но когда он пытается вернуть данные в ServiceA, он блокируется.

Я предполагаю, что это связано с тем, что когда я вызывал в ServiceA из «пользователя», он получил порт завершения ввода-вывода «блокировка доставки» (или, возможно, он называется блокировкой WCF за сеанс). В любом случае блокировка Я предполагаю, что, когда ServiceB's GetDataB() пытается вернуть значение, то, что действительно сделано, перевернуто вокруг канала и пытается вызвать метод приема на ServiceA, который требует блокировки и взаимоблокировок.

in каждый вопрос, который я прочитал до сих пор, где люди спрашивают: «Хорошо ли цепочки одного сервиса от другого», каждый (глупый) ответ был «уверен!», не заходите в него! Службы не знают, вызывается обычным кодом .NET или если их вызывают из другой службы! ». Раздражает. вещь к нему ", даже если это немного немного тривиально.

Я читал, что не могу отмечать методы, возвращающие значения как «один путь». И обозначение их как «повторного участника» ... должно ли это работать или нет? Я знаю, что, если я нахожусь в своем сервисе, я вызываю обратный вызов, блокировка тихо открывается. Что, если я позвоню другому сервису? WCF достаточно умна, чтобы освободить замок в этом случае?

Я мог бы пометить свои услуги как «несколько» вместо «повторного входа», но мне интересно (а) - это тупик действительно из того, что я думаю, или это может быть от чего-то другого, и (б) есть ли лучший способ обойти это?

+0

«Глупые» ответы, которые вы видели, так, потому что просто привязка служебных вызовов (обычно) действительно просто «глупо» проста. В вашем конкретном случае должно быть что-то еще. Включили/посмотрели [трассировку WCF] (http://stackoverflow.com/a/4271597/21567)? Возможно, вы захотите предоставить дополнительную (техническую) информацию о своей настройке (код, конфиг и т. Д.). –

+0

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

+0

так ... тупик «не должен» произойти? Если указатель стека в данный момент находится в методе GetDataA() ServiceA, и я вызываю метод GetDataB() ServiceB, и GetDataB() выполняет и пытается перезвонить мне с результирующими данными, он не должен блокироваться, пытаясь принять блокировка приема обратно в ServiceA? Я написал тестовое приложение, чтобы продемонстрировать это, один с двумя службами, и я удивлен, что НЕ вижу его в тупике, но я не могу понять, почему он не заторможен. Разве это не должно быть? Когда B пытается вернуть данные в A, не следует ли пытаться получить блокировку и потерпеть неудачу? –

ответ

1

Выяснил это. И я должен быть честным, я начал изучать WCF, читая MSDN, но он гудел и продолжал, поэтому я перешел к некоторым онлайн-книгам WCF (By Lowy & others). Мне следовало читать MSDN.

Я получил этот ответ от одного из разработчиков на WCF команде:

«Замок не происходит на транспортном уровне, это происходит в контексте экземпляра слоя Когда клиент в услуге А делает. исходящий запрос-ответ на услугу B, ответ не возвращается к сервису A, он возвращается к клиенту для службы B, который использует служба A ».

Это имеет смысл. Но в дополнение к этой информации я также узнал об этом:

«Если вы используете службы WCF для вызова любого метода (call out = callback или другой службы WCF), и вы помечены как« reenttrant », WCF освободит InstanceLock ».

(Таким образом, тупиковая я вижу выше (возможно) моя вина ...)

Я нашел этот лакомый здесь:

https://channel9.msdn.com/Forums/TechOff/254330-WCF-ConcurrencyModeReentrant-Confusion

И это привело меня к этому ценна статья здесь: Quote

https://msdn.microsoft.com/en-us/library/aa395214(v=vs.110).aspx

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