Метод Abort() прокси-сервера клиента wcf не освобождает сеанс после обнаружения исключения FaultException

#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. Этот ответ был бы более полезным, если бы он включал объяснение того, почему вы используете этот метод.