Когда в документации говорится «изящно», это действительно говорит о том, что вы вызываете ICommunicationObject.Close
со стороны клиента . На стороне service , если вы попытаетесь закрыть канал, пока клиент все еще ожидает ответа, у вас будет плохое время.
Клиент будет сбит с толку, не удосужившись подтвердить закрытие, затем сервер истечет время его попытки Close
, что в вашем случае происходит в рабочем потоке, а необработанные исключения в рабочих потоках не годятся для здоровье вашей службы или ваше собственное здравомыслие.
То, что вы действительно хотите, вовсе не изящное закрытие соединения, вы хотите принудительно отключить клиентов, которые не могут успешно войти в систему. Для этого вам нужно зарегистрировать обработчик событий, когда операция будет завершена, после будет отправлен ответ:
public string Login(string name, string pass)
{
if (name != pass)
{
OperationContext.Current.OperationCompleted += LoginFailed;
return "fail";
}
return "yay";
}
private void LoginFailed(object sender, EventArgs e)
{
OperationContext.Current.Channel.Abort();
}
Это будет делать то, что я уверен, что вы хотите - отправить «сбой» обратно клиенту, очистить все, что нужно очистить, а затем отключить клиент, предотвращая любую дальнейшую активность в сеансе.
Между прочим, я не знаю, насколько это близко к реальному коду сервиса, но немного избыточно иметь метод «Логин» в сервисе, когда вы можете просто использовать встроенную в WCF систему учетных данных сервиса.