更新
诚然,这是一段有点枯燥的代码。我目前更喜欢这个链接的答案,并且没有看到其中任何可能会在未来引起问题的“黑科技”。
这是微软处理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();
}
附加信息
许多人似乎在WCF上问这个问题,微软甚至创建了一个专门的示例来演示如何处理异常:
c:\WF_WCF_Samples\WCF\Basic\Client\ExpectedExceptions\CS\client
下载示例:C# 或 VB
考虑到
使用语句、
(激烈的?)内部讨论 和
线程 上存在很多问题,我不打算浪费时间尝试成为一个代码牛仔并找到更简洁的方法。对于我的服务器应用程序,我只会咬紧牙关,采用这种冗长但可信的方式实现 WCF 客户端。
可选的其他故障捕获
许多异常都源自
CommunicationException
,我认为大多数这些异常都不应该重试。我在 MSDN 上钻研了每个异常,并列出了一份可以重试的异常短列表(除了上面提到的
TimeOutException
)。如果我漏掉了一个需要重试的异常,请告诉我。
Exception mostRecentEx = null;
for(int i=0; i<5; i++)
{
try
{
...
double result = client.Add(value1, value2);
...
client.Close();
}
catch (ChannelTerminatedException cte)
{
mostRecentEx = cte;
secureSecretService.Abort();
Thread.Sleep(1000 * (i + 1));
}
catch (EndpointNotFoundException enfe)
{
mostRecentEx = enfe;
secureSecretService.Abort();
Thread.Sleep(1000 * (i + 1));
}
catch (ServerTooBusyException stbe)
{
mostRecentEx = stbe;
secureSecretService.Abort();
Thread.Sleep(1000 * (i + 1));
}
catch(Exception ex)
{
throw ex;
}
}
if (mostRecentEx != null)
{
throw new Exception("WCF call failed after 5 retries.", mostRecentEx );
}
using
语句,这违背了微软的建议。微软内部的讨论显然希望生产应用程序具有特定的结构化异常处理。这将是冗长而烦人的,但我想我需要接受它。 - makerofthings7