c# - "using"语句中出现异常,WCF 未正确关闭连接。如何关闭有故障的 WCF 客户端连接或有异常的连接?

标签 c# wcf exception proxy using-statement

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

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

当我在服务器上设置断点并让客户端挂起一分钟以上时,我对这种技术有疑问。 (我故意创建一个超时异常)

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

关于 TimeOutException 看来客户端的 retry() 逻辑将继续一遍又一遍地向服务器重新提交查询,我可以在哪里看到服务器端调试器将请求排队然后同时执行每个排队的请求。我的代码不希望 WCF 以这种方式运行,这可能是我所看到的数据损坏问题的原因。

有些东西并不完全符合这个解决方案。

What is the all-encompassing modern way of dealing with faults and exceptions in a WCF proxy?

最佳答案

更新

不可否认,这是一些普通的代码。 I currently prefer this linked answer ,并且不要在该代码中看到任何可能导致问题的“黑客攻击”。


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

有关详细信息,请参阅:Expected Exceptions

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();
}

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

c:\WF_WCF_Samples\WCF\Basic\Client\ExpectedExceptions\CS\client

下载示例: C#VB

考虑到这么多问题involving the using statement , (heated?) Internal discussionsthreads在这个问题上,我不会浪费时间试图成为一名代码牛仔并找到一种更清洁的方法。我将吸收它,并以这种冗长(但值得信赖)的方式为我的服务器应用程序实现 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 );
}

关于c# - "using"语句中出现异常,WCF 未正确关闭连接。如何关闭有故障的 WCF 客户端连接或有异常的连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5048624/

相关文章:

c# - 如何访问 web api Controller 中的 mvc Controller 以从 View 中获取 pdf

c# - 我可以简化使用 Observable.Create 从 json 请求返回对象吗

c# - 即时生成或更新 OperationContract

c# - 防火墙后面的 WCF 服务生成错误的 wsdl URI

java - 是什么导致了 java.lang.ArrayIndexOutOfBoundsException 以及如何防止它?

c# - 如何在您的网站上联系两个人

wcf - MSMQ 和 WCF 合约 - future 的增强功能

java - 抛出什么异常 - "Wrong Scenario"(Java)

java - 如何在 Cloud Endpoints 中返回自定义错误代码?

c# - 在 C# 中是否可以检查给定的日期格式字符串是否仅包含日期格式或时间格式?