- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在尝试扩展 this answer on SO使 WCF 客户端重试暂时性网络故障并处理 other situations that require a retry such as authentication expiration.
问题:
需要处理的WCF异常有哪些,正确的处理方式是什么?
以下是我希望看到的一些示例技术,它们可以代替 proxy.abort()
或作为补充:
由于不可能有人知道所有异常或解决它们的方法,因此请分享您所知道的。我将在下面的代码示例中汇总答案和方法。
// USAGE SAMPLE
//int newOrderId = 0; // need a value for definite assignment
//Service<IOrderService>.Use(orderService=>
//{
// newOrderId = orderService.PlaceOrder(request);
//}
/// <summary>
/// A safe WCF Proxy suitable when sessionmode=false
/// </summary>
/// <param name="codeBlock"></param>
public static void Use(UseServiceDelegateVoid<T> codeBlock)
{
IClientChannel proxy = (IClientChannel)_channelFactory.CreateChannel();
bool success = false;
try
{
codeBlock((T)proxy);
proxy.Close();
success = true;
}
catch (CommunicationObjectAbortedException e)
{
// Object should be discarded if this is reached.
// Debugging discovered the following exception here:
// "Connection can not be established because it has been aborted"
throw e;
}
catch (CommunicationObjectFaultedException e)
{
throw e;
}
catch (MessageSecurityException e)
{
throw e;
}
catch (ChannelTerminatedException)
{
proxy.Abort(); // Possibly retry?
}
catch (ServerTooBusyException)
{
proxy.Abort(); // Possibly retry?
}
catch (EndpointNotFoundException)
{
proxy.Abort(); // Possibly retry?
}
catch (FaultException)
{
proxy.Abort();
}
catch (CommunicationException)
{
proxy.Abort();
}
catch (TimeoutException)
{
// Sample error found during debug:
// The message could not be transferred within the allotted timeout of
// 00:01:00. There was no space available in the reliable channel's
// transfer window. The time allotted to this operation may have been a
// portion of a longer timeout.
proxy.Abort();
}
catch (ObjectDisposedException )
{
//todo: handle this duplex callback exception. Occurs when client disappears.
// Source: https://stackoverflow.com/questions/1427926/detecting-client-death-in-wcf-duplex-contracts/1428238#1428238
}
finally
{
if (!success)
{
proxy.Abort();
}
}
}
最佳答案
编辑:多次关闭和重新打开客户端似乎效率低下。我是 exploring solutions here如果找到,将更新和扩展此代码。 (或者如果 David Khaykin 发布了一个答案,我会将其标记为已接受)
经过几年的修改,下面的代码是我处理 WCF 重试和处理异常的首选策略 ( after seeing this blog posting from the wayback machine)。
我调查了每一个异常,我想对那个异常做什么,并注意到一个共同的特征;每个需要从公共(public)基类继承的“重试”的异常。我还注意到,每个将客户端置于无效状态的 permFail 异常也来自共享基类。
以下示例捕获客户端可以通过的每个 WCF 异常,并且可以针对您自己的自定义 channel 错误进行扩展。
WCF 客户端使用示例
生成客户端代理后,您只需执行此操作即可。
Service<IOrderService>.Use(orderService=>
{
orderService.PlaceOrder(request);
}
ServiceDelegate.cs
将此文件添加到您的解决方案中。不需要对此文件进行任何更改,除非您想更改重试次数或要处理的异常。
public delegate void UseServiceDelegate<T>(T proxy);
public static class Service<T>
{
public static ChannelFactory<T> _channelFactory = new ChannelFactory<T>("");
public static void Use(UseServiceDelegate<T> codeBlock)
{
IClientChannel proxy = null;
bool success = false;
Exception mostRecentEx = null;
int millsecondsToSleep = 1000;
for(int i=0; i<5; i++) // Attempt a maximum of 5 times
{
// Proxy cann't be reused
proxy = (IClientChannel)_channelFactory.CreateChannel();
try
{
codeBlock((T)proxy);
proxy.Close();
success = true;
break;
}
catch (FaultException customFaultEx)
{
mostRecentEx = customFaultEx;
proxy.Abort();
// Custom resolution for this app-level exception
Thread.Sleep(millsecondsToSleep * (i + 1));
}
// 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;
proxy.Abort();
// delay (backoff) and retry
Thread.Sleep(millsecondsToSleep * (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;
proxy.Abort();
// delay (backoff) and retry
Thread.Sleep(millsecondsToSleep * (i + 1));
}
// The following exception that is thrown when a server is too busy to accept a message.
catch (ServerTooBusyException stbe)
{
mostRecentEx = stbe;
proxy.Abort();
// delay (backoff) and retry
Thread.Sleep(millsecondsToSleep * (i + 1));
}
catch (TimeoutException timeoutEx)
{
mostRecentEx = timeoutEx;
proxy.Abort();
// delay (backoff) and retry
Thread.Sleep(millsecondsToSleep * (i + 1));
}
catch (CommunicationException comException)
{
mostRecentEx = comException;
proxy.Abort();
// delay (backoff) and retry
Thread.Sleep(millsecondsToSleep * (i + 1));
}
catch(Exception e)
{
// rethrow any other exception not defined here
// You may want to define a custom Exception class to pass information such as failure count, and failure type
proxy.Abort();
throw e;
}
}
if (success == false && mostRecentEx != null)
{
proxy.Abort();
throw new Exception("WCF call failed after 5 retries.", mostRecentEx );
}
}
}
关于c# - 如何处理 WCF 异常(带代码的综合列表),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6130331/
这一次将使用pymysql来进行一次对MySQL的增删改查的全部操作,相当于对前五次的总结: 先查阅数据库: 现在编写源码进行增删改查操作,源码为: ?
我收到警告: One or more signals are missing in the sensitivity list of always block. always@(Address)begi
我正在寻找一个完整的 java 日期管理库,它可以让我理解像这样的字符串: 明天中午 => 2011-10-20 12:00 今天下午 4 点 => 2011-10-20 16:00 等... 但如果
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 7年前关闭。 Improve this questi
下学期我可能会成为我大学网络编程类(class)教学团队的一员,我想知道要给学生布置什么样的 Javascript 作业。从编程的 Angular 来看,本类(class)不是入门类(class)。
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
已结束。此问题不符合 Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题对于 Stack Overflow 来说
我将我的 Gitlab 迁移到了新域。我想将所有 HTTP 请求从旧 URL 重定向到新 URL。两个域当前都指向同一服务器(使用 A DNS 记录)。 我使用 Gitlab Omnibus 包,并捆
只需在新配置的 CentOS 6.5 VM 上使用 omnibus 安装程序设置新的 Gitlab 安装。我有点 Linux 菜鸟,但我一直在尝试设置 Gitlab 安装,并且能够通过主机访问安装。
我试图更好地了解合成如何在没有指定其他条件的过程中工作。 我认为这不是编码方式,因为我没有考虑其他选项,但我的问题是如何解释这段代码? process(clock) begin if (clock'e
创建以下内容时: create view v (a, b) as select 1, 2 from dual; create or replace package p as type t is t
我是一名优秀的程序员,十分优秀!