【问题标题】:Abort() method of wcf client proxy doesn't release session after catching FaultExceptionwcf 客户端代理的 Abort() 方法在捕获 FaultException 后不释放会话
【发布时间】:2011-04-24 07:56:10
【问题描述】:

我创建了一个托管在 IIS 和 wcf 客户端中的简单 wcf 服务,并发现当你从 wcf 服务捕获一个 FaultException 然后调用 client.Abort() 来释放会话时(正如微软示例所说)它不会'不释放会话并在第 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();
            }
      }  
   }              

}

但是,如果您将 client.Abort() 替换为 client.Close() 以获得 catch(FaultException ),那么一切都会像魅力一样工作,并且在第 11 次调用 wcf-service 方法后没有锁定。

为什么会这样?为什么捕获到 FaultException 后 Abort() 方法不清理会话?

【问题讨论】:

标签: c# wcf faultexception


【解决方案1】:

两件事:

  • Abort() 应在通信通道处于故障状态时使用。使用Close() 使客户端尝试与服务进行通信,告诉它关闭服务实例,如果你愿意的话。如果通信通道处于故障状态,则意味着无法从客户端到服务进行通信。在这种情况下,您应该调用Abort(),以便至少关闭 client。服务实例/会话在服务器上仍然是活动的(因为两者之间没有通信),并且会一直保持到实例超时发生。如果您在故障通道上调用了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();
            }
            }
      }  
    }              
    

    【讨论】:

    • 这个答案如果包含你为什么使用这种方法的解释会更有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-01
    • 2013-01-13
    • 1970-01-01
    • 2013-05-07
    • 2013-04-09
    相关资源
    最近更新 更多