#c# #wcf #faultexception
#c# #wcf #исключение faultexception
Вопрос:
Я создал простую службу wcf, размещенную в IIS и wcf клиенте, и выяснил, что когда вы перехватываете FaultException из службы wcf, а затем вызываете client.Abort() для освобождения сеанса (как указано в примерах Microsoft), он не освобождает сеанс и зависает при 11-м вызове.
Вот пример:
Служба Wcf:
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
public class Service1 : IService1
{
public string GetData(int value)
{
throw new FaultException("Exception is here");
return string.Format("You entered: {0}", value);
}
}
Клиент:
class Program
{
static void Main(string[] args)
{
Service1Client client = null;
for(int i = 0; i < 15; i )
{
try
{
client = new Service1Client();
client.GetData(100);
}
catch (TimeoutException timeoutEx)
{
Console.WriteLine(timeoutEx);
client.Abort();
}
catch (FaultException faultEx)
{
Console.WriteLine(faultEx);
client.Abort();
}
catch (CommunicationException commEx)
{
Console.WriteLine(commEx);
client.Abort();
}
}
}
}
Но если вы замените клиента.Прервать () с клиентом.Close() для catch(FaultException ) тогда все работает как по волшебству, и после 11-го вызова метода wcf-service блокировки нет.
Почему это может быть? Почему метод Abort() не очищает сеанс после обнаружения FaultException?
Комментарии:
1. Вы только что скопировали вставили его отсюда? social.msdn.microsoft.com/Forums/en-US/wcf/thread /…
Ответ №1:
Две вещи:
Abort()
должен использоваться, когда канал связи находится в состоянии сбоя. ИспользованиеClose()
заставляет клиента пытаться связаться со службой, сообщая ему закрыть экземпляр службы, изящно, если хотите. Если канал связи находится в состоянии сбоя, это означает, что связь между клиентом и службой невозможна. В этой ситуации вы должны вызвать,Abort()
чтобы, по крайней мере, клиент был закрыт. Экземпляр службы / сеанс все еще будет активен на сервере (поскольку между ними нет связи) и будет оставаться таковым до тех пор, пока не наступит тайм-аут экземпляра. Если бы вы вызывалиClose()
по каналу с ошибкой, это выдало бы больше ошибок.- Ваша служба выдает
FaultException
. Это не означает, что канал связи будет переведен в состояние сбоя. т. е. вы все еще можете совершать вызовы, используя тот же клиент. И, как таковой, в вашем примере вы не должны вызыватьAbort()
.
tl;dr Abort()
закрывает только клиент. Экземпляр службы / сеанс все еще активен.
Вы можете проверить состояние канала связи, используя:
ICommunicationObject comObj = ((ICommunicationObject)client);
if(comObj.State == CommunicationState.Faulted)
client.Abort();
else
client.Close();
Ответ №2:
Вы пробовали этот способ, который я использую для вызова WCF?
class Program
{
static void Main(string[] args)
{
for(int i = 0; i < 15; i )
{
using Service1Client client = new Service1Client()
{
try
{
client.GetData(100);
}
catch (TimeoutException timeoutEx)
{
Console.WriteLine(timeoutEx);
client.Abort();
}
catch (FaultException faultEx)
{
Console.WriteLine(faultEx);
client.Abort();
}
catch (CommunicationException commEx)
{
Console.WriteLine(commEx);
client.Abort();
}
finally
{
client.Close();
}
}
}
}
Комментарии:
1. Этот ответ был бы более полезным, если бы он включал объяснение того, почему вы используете этот метод.