В моем собственном тестировании ключом является то, является ли используемая привязка ориентированной на сеанс или нет. Если вы используете привязку без сохранения состояния, такую как BasicHttpBinding, вы можете испортить канал, сколько захотите, и у вас все хорошо. Например, у меня есть сервис WCF, использующий BasicHttpBinding, который выглядит следующим образом - обратите внимание на вызов Channel.Abort () в SayGoodbye ():
public class HelloWorldService : IHelloWorldService
{
public string SayHello()
{
return "Hello.";
}
public string SayGoodbye()
{
OperationContext.Current.Channel.Abort();
return "Goodbye.";
}
}
И код клиента Silverlight выглядит следующим образом (ужасно, черт возьми).
public partial class ServiceTestPage : Page
{
HelloWorldServiceClient client;
public ServiceTestPage()
{
InitializeComponent();
client = new HelloWorldServiceClient();
client.SayHelloCompleted += new EventHandler<SayHelloCompletedEventArgs>(client_SayHelloCompleted);
client.SayGoodbyeCompleted += new EventHandler<SayGoodbyeCompletedEventArgs>(client_SayGoodbyeCompleted);
client.SayHelloAsync();
}
void client_SayHelloCompleted(object sender, SayHelloCompletedEventArgs e)
{
if (e.Error == null)
{
Debug.WriteLine("Called SayHello() with result: {0}.", e.Result);
client.SayGoodbyeAsync();
}
else
{
Debug.WriteLine("Called SayHello() with the error: {0}", e.Error.ToString());
}
}
void client_SayGoodbyeCompleted(object sender, SayGoodbyeCompletedEventArgs e)
{
if (e.Error == null)
{
Debug.WriteLine("Called SayGoodbye() with result: {0}.");
}
else
{
Debug.WriteLine("Called SayGoodbye() with the error: {0}", e.Error.ToString());
}
client.SayHelloAsync(); // start over
}
}
И он будет бесконечно зацикливаться столько, сколько вы захотите.
Но если вы используете привязку к сеансу, такую как Net.TCP или HttpPollingDuplex, вы должны быть намного осторожнее с обработкой канала. Если это так, то конечно вы кешируете свой прокси-клиент, верно? В этом случае вам нужно перехватить событие Channel_Fapted, прервать работу клиента, а затем воссоздать его и, конечно, заново установить все обработчики событий. Вид боли.
В дополнение к этому, когда дело доходит до использования дуплексного связывания, лучший подход, который я нашел (я открыт для других), - это создать оболочку для моего прокси-клиента, которая выполняет три действия:
(1) Преобразует неприятный код, вызывающий события, сгенерированный диалоговым окном «Добавить ссылку на службу», в гораздо более полезный шаблон прохождения продолжения.
(2) Переносит каждое из событий, созданных на стороне сервера, чтобы клиент мог подписаться на событие в моей оболочке, а не на событие самого прокси-клиента, поскольку сам прокси-клиент, возможно, придется удалить и воссоздан.
(3) Обрабатывает событие ChannelFaults и (несколько раз с тайм-аутом) пытается воссоздать прокси-клиент. Если это удается, он автоматически повторно подписывает все свои обертки событий, и если это происходит неуспешно, он генерирует событие real ClientFapted, которое фактически означает: «Вы облажались, попробуйте позже».
Это боль, так как кажется, что это именно та вещь, которая должна была быть включена в сгенерированный MS код в первую очередь. Но это, безусловно, решает множество проблем. На днях я посмотрю, смогу ли я заставить эту оболочку работать с шаблонами T4.