“使用”中的异常语句与WCF不正确关闭连接。如何关闭WCF客户端连接错误或异常情况? [英] Exception in "using" statement with WCF not closing connections properly. How does one close faulted WCF client connections or those with exceptions?

查看:169
本文介绍了“使用”中的异常语句与WCF不正确关闭连接。如何关闭WCF客户端连接错误或异常情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

There are several questions on StackOverflow regarding closing WCF connections, however the highest ranking answers refers to this blog:

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

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

I have a problem with this technique when I set a breakpoint at the server and let the client hang for more than one minute. (I'm intentionally creating a timeout exception)

问题是客户端似乎挂起,直到服务器完成处理。我的猜测是,一切正在清理后的例外。

The issue is that the client appears to "hang" until the server is done processing. My guess is that everything is being cleaned up post-exception.

关于 TimeOutException ,似乎 retry()客户端的逻辑将继续重新将查询重新提交给服务器,我可以看到服务器端调试器排队请求然后并发执行每个排队的请求。我的代码不希望WCF这样做,可能是我看到的数据损坏问题的原因。

In regard to the TimeOutException it appears that the retry() logic of the client will continue to resubmit the query to the server over and over again, where I can see the server-side debugger queue up the requests and then execute each queued request concurrently. My code wan't expecting WCF to act this way and may be the cause of data corruption issues I'm seeing.

这个解决方案并不完全相同

Something doesn't totally add up with this solution.


WCF代理中处理错误和异常
的全面的现代方式是

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


推荐答案

更新

诚然,这是一个平凡的代码写。 我目前更喜欢这个链接的答案,并且没有看到该代码中可能会导致问题的任何黑客。

Admittedly, this is a bit of mundane code to write. I currently prefer this linked answer, and don't see any "hacks" in that code that may cause issues down the road.

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

This is Microsoft's recommended way to handle WCF client calls:

有关更多详细信息,请参阅:预期的异常

For more detail see: 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问这个问题,Microsoft甚至创建了一个专门的示例来演示如何处理异常:

Additional information So many people seem to be asking this question on WCF that Microsoft even created a dedicated sample to demonstrate how to handle exceptions:

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

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

下载示例:
C# VB

考虑到有这么多问题涉及到使用声明线程在这个问题上,我不会浪费我的时间试图成为一个代码牛仔,找到一个更干净的方式。我只是吸吮它,并为我的服务器应用程序实现WCF客户端这种冗长(但可信赖的)方式。

Considering that there are so many issues involving the using statement, (heated?) Internal discussions and threads on this issue, I'm not going to waste my time trying to become a code cowboy and find a cleaner way. I'll just suck it up, and implement WCF clients this verbose (yet trusted) way for my server applications.

可选附加失败捕获

许多异常来源于 CommunicationException ,我不认为应该重试大多数这些异常。我在MSDN上排除了每个异常,并发现了一个可重试异常的简短列表(除了 TimeOutException 以上)。如果我错过了应该重试的异常,请告诉我。

Many exceptions derive from CommunicationException and I don't think most of those exceptions should be retried. I drudged through each exception on MSDN and found a short list of retry-able exceptions (in addition to TimeOutException above). Do let me know if I missed an exception that should be retried.

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

这篇关于“使用”中的异常语句与WCF不正确关闭连接。如何关闭WCF客户端连接错误或异常情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆