Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF服务无法捕获客户端';撞车_C#_Wcf_Tcp_Duplex Channel - Fatal编程技术网

C# WCF服务无法捕获客户端';撞车

C# WCF服务无法捕获客户端';撞车,c#,wcf,tcp,duplex-channel,C#,Wcf,Tcp,Duplex Channel,我已经创建了一个使用NetTCP绑定的WCF服务 我的服务由客户端访问,保存其回调通道,并在以后使用它调用客户端(这是一个持久的tcp连接)。一切正常,但如果我决定突然杀死客户端,我会得到一个无法捕获的SocketException(“远程主机强制关闭了一个现有连接”) 我已经试过什么了? 我已经在使用回调通道的每个方法中添加了try-catch子句,甚至在更高级别中也添加了try-catch子句,即启动我的服务的WCFHost 我已尝试获取通道和回调通道,并添加了处理通道故障事件的方法: va

我已经创建了一个使用NetTCP绑定的WCF服务

我的服务由客户端访问,保存其回调通道,并在以后使用它调用客户端(这是一个持久的tcp连接)。一切正常,但如果我决定突然杀死客户端,我会得到一个无法捕获的SocketException(“远程主机强制关闭了一个现有连接”)

我已经试过什么了?

  • 我已经在使用回调通道的每个方法中添加了try-catch子句,甚至在更高级别中也添加了try-catch子句,即启动我的服务的WCFHost

  • 我已尝试获取通道和回调通道,并添加了处理通道故障事件的方法:

    var channel = OperationContext.Current.Channel; 
    channel.Faulted += ChannelFaulted;
    var callbackChannel = OperationContext.Current.GetCallbackChannel<CallbackInterface>();
    var comObj = callbackChannel as ICommunicationObject;
    comObj.Faulted += ChannelFaulted;
    
    var channel=OperationContext.Current.channel;
    channel.Faulted+=ChannelFaulted;
    var callbackChannel=OperationContext.Current.GetCallbackChannel();
    var comObj=作为ICommunicationObject的回调通道;
    comObj.Faulted+=信道故障;
    

  • 简言之,我试图在服务器端处理客户端引发的异常。

    WCF服务有两种方式支持异常处理:

    1.在hosts.config文件中将serviceDebug.includeExceptionDetailInFaults属性定义为“true” 2.在服务类上将includeExceptionDetailInFaults属性定义为“true”

    例如:

    配置文件解决方案:

    <behaviors>
    <serviceBehaviors>
    <behavior name=”ServiceBehavior”>
    <serviceMetadata httpGetEnabled=”true”/>
    <serviceDebug includeExceptionDetailInFaults=”true”/>
    </behavior>
    </serviceBehaviors>
    </behaviors>
    
    [ServiceBehavior(IncludeExceptionDetailInFaults=true)]
    public class CustomersService : ICustomersService
    {
    private CustomerDetail customerDetail = null;
    
    …等等

    抛出异常 将includeExceptionDetailInFaults设置为true是在WCF中支持异常的第一步

    下一步是让您的服务抛出FaultException异常(System.ServiceModel.FaultException命名空间中的一个类)。 请注意,当您希望从WCF主机向WCF客户端抛出异常时,不能期望仅使用典型的异常类。 要在WCF绑定上抛出异常,需要使用FaultException类

    抛出故障异常示例

    try
    {
    //Try to do stuff
    }
    catch
    {
    throw new FaultException(“Full ruckus!”);
    }
    
    捕获故障异常示例

    try
    {
    //Try to do stuff
    }
    catch
    {
    throw new FaultException(“Full ruckus!”);
    }
    
    现在WCF客户端可以捕获FaultException

    try
    {
    //Client calls services off the proxy
    }
    catch(FaultException fa)
    {
    MessageBox.Show(fa.Message);
    }
    
    区分故障异常的类型 FaultException类是WCF异常的通用类。为了确定发生何种类型的FaultException,可以使用FaultCode类。 在WCF服务上,FaultCode实现如下所示:

    try
    {
       //Connect to a database
    }
    catch
    {
       throw new FaultException(“Full ruckus!”, new FaultCode(“DBConnection”));
    }
    
     try
        {
           //Call services via the proxy
        }
        catch(FaultException fa)
        {
           switch(fa.Code.Name)
           {
             case “DBConnection”:
               MessageBox.Show(“Cannot connect to database!”);
               break;
             default:
               MessageBox.Show(“fa.message”);
               break;
            }
        }
    
    在WCF客户端上,FaultCode实现如下所示:

    try
    {
       //Connect to a database
    }
    catch
    {
       throw new FaultException(“Full ruckus!”, new FaultCode(“DBConnection”));
    }
    
     try
        {
           //Call services via the proxy
        }
        catch(FaultException fa)
        {
           switch(fa.Code.Name)
           {
             case “DBConnection”:
               MessageBox.Show(“Cannot connect to database!”);
               break;
             default:
               MessageBox.Show(“fa.message”);
               break;
            }
        }
    

    有关更多信息,您可以查看,也可以

    经过大量调查,服务器可以检测客户端使用我在问题前面提到的故障事件引发的异常(我应该在调试时更加耐心,直到异常“爬升”到所有级别,直到到达我的代码)


    但是,请注意,事件仅在为时已晚时捕获异常:通道已为null(OperationContext.Current也是如此)。即使在尝试使用IServiceBehavior和IEndpointBehavior(设置了iChannelinizator)时,我也无法捕获System.ServiceModel.dll引发的原始SocketException。当我的ChannelFaulture()方法最终被调用时,无法检测哪个客户机失败。

    谢谢,但我的问题是我无法捕获异常,因此无法中止或关闭通道。我在Visual Studio中看到了一个异常,但它没有链接到代码中的任何一行,并且我的try-catch子句都没有捕捉到它。您能提供更多代码吗?谢谢您的回答。我尝试使用ServiceBehavior,但仍然无法捕获异常(尽管我在调试器中看到了ApplyDispatcherBehavior的代码)@G.madn您是否尝试了我附加的第二个链接?是的。一旦发现错误,您提供的信息对于处理错误非常有用。然而,我的问题是,一开始我没能抓住错误。我实际上在寻找一种检测客户端崩溃的方法,这样我的服务就不会为不存在的客户端存储空闲连接。