Помогает ли состояние неисправности канала WCF вообще? - PullRequest
3 голосов
/ 28 февраля 2011

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

Взять, к примеру, TCP. Большая часть связи по протоколу TCP отключена. Так с какой стати одно соединение сломало бы канал и разорвало все следующие соединения?

А именованные трубы?

Может быть, я ошибаюсь. Поэтому, пожалуйста, объясните, почему это функция, а не ошибка.

Ответы [ 3 ]

11 голосов
/ 28 февраля 2011

Я думаю, что это продукт общей философии WCF Юваля Леви (одного из архитекторов WCF).Цитируя его книгу Программирование служб WCF :

Эта [система исключений и обычный способ ее использования] является фундаментальным недостатком .NET как платформы.[...] Здесь [после создания исключения] произошло нечто совершенно неожиданное и ужасное.Как клиент мог притворяться иначе?Объект может быть безнадежно сломан, и все же клиент продолжает его использовать.

Идея состоит в том, что вы, в конце концов, общаетесь с объектом по другую сторону от того, что изиспользуемый вами транспортный канал, и, если объект выдает исключение, он может перестать использоваться.Это интересный момент, но я не уверен, что полностью согласен (поскольку, как вы говорите, на практике это может сильно раздражать).

7 голосов
/ 28 февраля 2011

Faulted - это одно из состояний конечного автомата CommunicationObject, которое встроено в реализацию многих абстракций WCF. По сути, это означает «игра окончена» для этого объекта, поэтому вы не найдете способа отключить его.

Это, конечно, не ошибка: конечный автомат CommunicationObject, лежащий в основе всех этих артефактов, был осознанным выбором дизайна. Хотя это может представлять интерес для обсуждения проектных решений, принятых архитекторами WCF, в конечном счете, вам просто нужно признать, что все так и происходит, если вы хотите использовать WCF.

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

Даже глядя на детали конкретных привязок, вы обнаружите очень мало элементов стека, которые являются отказоустойчивыми в той степени, в которой вы могли бы безопасно использовать их после неудачной попытки предыдущей связи (например, HTTP-протокол). Даже те, которые вы упоминаете (TCP, Named Pipes), не так отказоустойчивы, как вы предлагаете.

Я думаю, что конечный автомат CommunicationObject, или что-то в этом роде, более или менее необходим для того, чтобы иметь абстракцию канала, которая работает на более высоком уровне, чем мельчайшие детали всех составляющих ее слоев / элементов. Это включает простое правило: если это Faulted, выбросьте его и создайте новое. Да, может быть несколько случаев, когда при этом вы пропускаете оптимизацию, которая была бы возможна при сохранении некоторого ресурса, который можно было бы безопасно использовать повторно; но это (небольшая) стоимость, которую вы платите за работу с гораздо более простой абстракцией ваших коммуникаций.

0 голосов
/ 26 июля 2012

Вот что делает WCF:

Proxy a = new Proxy();
a.SomeOp() -> threw exception
a.SomeOtherOp() -> faulted

Здесь «SomeOp» не удалось, а не «a», так почему SomeOtherOp должен завершиться ошибкой?

Это имеет смысл, если

Proxy a = new Proxy(); -> threw exception
a.SomeOp() -> faulted
...