"使用"语句中的异常,WCF未正确关闭连接.如何关闭故障WCF客户端连接或具有异常的连接?

goo*_*ate 5 c# wcf proxy exception using-statement

关于关闭WCF连接的StackOverflow有几个问题,但排名最高的答案是指这个博客:

http://marcgravell.blogspot.com/2008/11/dontdontuse-using.html

当我在服务器上设置断点并让客户端挂起超过一分钟时,我遇到了这种技术的问题.(我故意创建超时异常)

问题是客户端似乎"挂起",直到服务器完成处理.我的猜测是,一切都在异常后被清理干净.

在考虑到TimeOutException它看来,retry()客户端的逻辑将继续一遍一遍重新提交查询到服务器,在那里我可以看到服务器端的调试器排队的请求,然后执行每一个排队的请求同时被.我的代码不希望WCF这样做,可能是我看到的数据损坏问题的原因.

有些东西并没有完全加入这个解决方案.

什么是在WCF代理中处理故障和异常的无所不包的现代方法?

goo*_*ate 7

更新

不可否认,这是一些平凡的代码. 我目前更喜欢这个链接的答案,并且在该代码中看不到任何可能导致问题的"黑客".


这是Microsoft推荐的处理WCF客户端调用的方法:

有关更多详细信息,请参阅:预期的例外情况

try
{
    ...
    double result = client.Add(value1, value2);
    ...
    client.Close();
}
catch (TimeoutException exception)
{
    Console.WriteLine("Got {0}", exception.GetType());
    client.Abort();
}
catch (CommunicationException exception)
{
    Console.WriteLine("Got {0}", exception.GetType());
    client.Abort();
}
Run Code Online (Sandbox Code Playgroud)

其他信息 很多人似乎在WCF上问这个问题,微软甚至创建了一个专门的示例来演示如何处理异常:

C:\ WF_WCF_Samples\WCF \基本\客户端\ ExpectedExceptions\CS \客户端

下载示例: C#VB

考虑到涉及使用声明的问题很多,(加热?)内部讨论线程就此问题,我不会浪费时间试图成为代码牛仔并找到一种更清洁的方式.我只是简单地说,并为我的服务器应用程序实现WCF客户端这种冗长(但可信)的方式.

可选的附加失败事件

许多例外来自CommunicationException,我认为大多数例外都不应该重审.我在MSDN上浏览了每个例外,并找到了一个可重试异常的简短列表(除了TimeOutException上面的内容).如果我错过了应该重试的异常,请告诉我.

Exception   mostRecentEx = null;
for(int i=0; i<5; i++)  // Attempt a maximum of 5 times 
{
    try
    {
       ...
       double result = client.Add(value1, value2);
       ...
       client.Close();
    }

    // The following is typically thrown on the client when a channel is terminated due to the server closing the connection.
    catch (ChannelTerminatedException cte)
    {

      mostRecentEx = cte;
      secureSecretService.Abort();
        //  delay (backoff) and retry 
        Thread.Sleep(1000 * (i + 1)); 
    }

    // The following is thrown when a remote endpoint could not be found or reached.  The endpoint may not be found or 
    // reachable because the remote endpoint is down, the remote endpoint is unreachable, or because the remote network is unreachable.
    catch (EndpointNotFoundException enfe)
    {

      mostRecentEx = enfe;
     secureSecretService.Abort();
        //  delay (backoff) and retry 
        Thread.Sleep(1000 * (i + 1)); 
    }

    // The following exception that is thrown when a server is too busy to accept a message.
    catch (ServerTooBusyException stbe)
    {
      mostRecentEx = stbe;
        secureSecretService.Abort();

        //  delay (backoff) and retry 
        Thread.Sleep(1000 * (i + 1)); 
    }

    catch(Exception ex)
    { 
         throw ex;  // rethrow any other exception not defined here
    }
}
if (mostRecentEx != null) 
{
    throw new Exception("WCF call failed after 5 retries.", mostRecentEx );
}
Run Code Online (Sandbox Code Playgroud)