我将WCF用于客户端服务器系统。 当我在服务器上向IService添加服务引用时,会生成代理类ServiceClient。 我的代码如下所示:
ServiceClient client = new ServiceClient();
try
{
client.Operation1();
}
catch(Exception ex)
{
// Handle Exception
}
try
{
client.Operation2();
}
catch(Exception ex)
{
// Handle Exception
}
问题是如果第一次调用中存在通信异常,则客户端的状态将更改为Faulted,并且我不知道如何重新打开它以进行第二次调用。有没有办法重新打开它?或者我应该创建一个新的并替换实例(它似乎不是一种优雅的方式)?
答案 0 :(得分:16)
一旦ICommunicationObject(您的WCF客户端对象)处于故障状态,“重新打开”它的唯一方法是创建一个新的。
ServiceClient client = new ServiceClient();
try
{
client.Operation1();
}
catch(Exception ex)
{
if (client.State == CommunicationState.Faulted)
{
client.Abort();
client = new ServiceClient();
}
}
try
{
client.Operation2();
}
catch(Exception ex)
{
// Handle Exception
}
答案 1 :(得分:5)
如果在第一次调用中存在导致故障状态的通信异常,则必须基本上“重新创建”WCF客户端代理。在你的例子中,我可能会做类似的事情:
if (client.State == CommunicationState.Faulted)
client = new ServiceClient();
如果连接出现故障,这将允许您“重新打开”连接。这可能看起来有点矫枉过正,但如果你在客户端获得通信异常,可能还有其他事情发生(即:服务器死了?服务器无响应?)
祝你好运答案 2 :(得分:4)
同意最后的答案,一旦失败,你需要中止。我们使用lambdas和类似下面的方法的组合来执行此操作:
public static void Use<TServiceInterface>(TServiceInterface proxy, Action handler)
{
Type proxyType = typeof(TServiceInterface);
IClientChannel channel = (IClientChannel)proxy;
try
{
handler();
_logSource.Log(LogLevel.Debug, string.Format("Closing client channel for '{0}' ...", proxyType.Name));
channel.Close();
_logSource.Log(LogLevel.Debug, string.Format("Client channel for '{0}' closed.", proxyType.Name));
}
catch
{
if (channel.State == CommunicationState.Faulted)
{
_logSource.Log(LogLevel.Debug, string.Format("Aborting client channel for '{0}' ...", proxyType.Name));
channel.Abort();
_logSource.Log(LogLevel.Debug, string.Format("Client channel for '{0}' aborted.", proxyType.Name));
}
else
{
_logSource.Log(LogLevel.Debug, string.Format("Closing client channel for '{0}' ...", proxyType.Name));
channel.Close();
_logSource.Log(LogLevel.Debug, string.Format("Client channel for '{0}' closed.", proxyType.Name));
}
throw;
}
}
这是对.net上已经存在的解决方案的略微修改,但它对于处理代理非常有用。然后,您可以在同一个lambda表达式中放置多个服务调用,并将其传递给方法。
答案 3 :(得分:0)
这很可能是由服务器端的未处理异常引起的。默认情况下,WCF运行时会终止您的服务实例,并在未处理的异常情况下将通道置于故障状态,并且您无法再通过该通道进行通信。因此,您需要与服务建立新会话。您应该在服务器端捕获异常并通过引发FaultException或定义FaultContract来发送soap错误。您还可以使用returnUnknownExceptionsAsFaults服务行为。