c#wcf - 在代理类上调用open()时抛出的异常

时间:2009-03-17 14:09:48

标签: c# wcf exception

我有以下问题,基本上我有一个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();
 }

4 个答案:

答案 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语句的问题在于,如果你遇到故障状态,它仍会尝试在块结束时关闭。另一个对我们来说至关重要的考虑因素是每次创建代理的成本。

我们从这些博客文章中学到了很多东西:

http://blogs.msdn.com/wenlong/archive/2007/10/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx

http://blogs.msdn.com/wenlong/archive/2007/10/27/performance-improvement-of-wcf-client-proxy-creation-and-best-practices.aspx

希望它也能帮到你。

干杯,瓦格纳。