我有以下问题,基本上我有一个WCF服务,在小测试中运行良好。但是,当我尝试批处理/加载测试时,在代理类上调用open()方法时,我会收到InvalidOperationException
消息:
“通信对象System.ServiceModel.Channels.ServiceChannel在处于”已打开“状态时无法修改。”
我搜索了谷歌,但找不到其他人真正引用此异常消息。
我想有关服务的一些进一步信息可能是诊断所必需的 - 当服务通过其中一个公开的方法接收数据时,它基本上执行一些处理并将数据路由到与数据相关的服务(不同的数据将导致不同的路由)。为了确保服务尽可能快地运行,数据的接收,处理和路由的每个循环由线程池中的单独线程处理。这可能是一个线程调用proxyClass.Open()
而另一个线程正在使用它的问题?如果这确实是问题,那么lock
块会消除这个问题吗?
谢谢你们, - 我已经在这个项目上工作了太长,最后想看到它的背面 - 但这似乎是最后的绊脚石,所以任何帮助都非常感激: - )
=============================================== ==========================
感谢您强调我不应该为WCF代理类使用using
构造。然而,MSDN文章并不是有史以来最清晰的文章,所以有一个简单的问题:我应该使用代理这样的文章:
try
{
client = new proxy.DataConnectorServiceClient();
client.Open();
//do work
client.Close();
}
.................. //catch more specific exceptions
catch(Exception e)
{
client.Abort();
}
答案 0 :(得分:2)
你是如何使用代理的?为每个调用创建新的代理对象。添加一些有关如何使用代理的代码。
使用代理的理想方式是为每次调用创建新代理并在完成后处理它。您正在为打开的代理调用proxy.open(),这是错误的。应该只调用一次。
最后尝试使用下面的内容,因为wcf没有处理失败的代理并且它堆积起来。不确定它会有所帮助但是试一试。
if (proxy.State == CommunicationState.Faulted)
{
proxy.Abort();
}
else
{
try
{
proxy.Close();
}
catch
{
proxy.Abort();
}
}
为什么要这样做? http://msdn.microsoft.com/en-us/library/aa355056.aspx
您在上面发布的代码可以使用,但您总是会吃异常。因此,在单独的catch中处理wcf相关的异常,并且使用Excelion的泛型catch会中止然后抛出异常。
try
{
...
client.Close();
}
catch (CommunicationException e)
{
...
client.Abort();
}
catch (TimeoutException e)
{
...
client.Abort();
}
catch (Exception e)
{
...
client.Abort();
throw;
}
此外,如果您仍然希望使用using语句,那么您可以覆盖代理中的dispose方法,并在出现wcf错误时使用abort方法进行处理。
并且不需要调用.Open(),因为它会在第一次调用时打开。
答案 1 :(得分:2)
我假设你使用的是.NET 3.5或更高版本。在.NET 3.5中,WCF ClientBase'1类(生成的客户端代理的基类)已更新为使用缓存的ChannelFactories / Channels。因此,除非您使用其中一个禁用缓存的客户端使用/创建策略(接收Binding对象的客户端构造函数,或者在创建支持通道之前访问某些特定属性之一),即使您正在创建一个新的客户端实例,它仍然可以使用相同的通道。换句话说,在调用.Open()之前,请始终确保您正在检查.Created状态。
答案 2 :(得分:1)
听起来好像你在同一个对象上多次调用Open()。
答案 3 :(得分:0)
我们遇到了与你前一段时间相同的障碍。
using语句的问题在于,如果你遇到故障状态,它仍会尝试在块结束时关闭。另一个对我们来说至关重要的考虑因素是每次创建代理的成本。
我们从这些博客文章中学到了很多东西:
和
希望它也能帮到你。
干杯,瓦格纳。