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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/654420/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 12:00:57  来源:igfitidea点击:

c# wcf - exception thrown when calling open() on proxy class

c#wcfexception

提问by

I have the following problem, basically i have a WCF service which operates fine in small tests. However when i attempt a batch/load test i get an InvalidOperationExceptionwith the message when the open() method is called on the proxy class:

我有以下问题,基本上我有一个 WCF 服务,它在小测试中运行良好。但是,当我尝试批处理/负载测试InvalidOperationException时,当在代理类上调用 open() 方法时,我会收到一条消息:

"The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be modified while it is in the Opened state."

“通信对象 System.ServiceModel.Channels.ServiceChannel 在处于打开状态时无法修改。”

I have searched google, but cannot find anyone else really quoting this exception message.

我搜索过谷歌,但找不到其他人真正引用此异常消息。

I guess some further info on the service may be necessary for a diagnosis - when the service receives data through one of it's exposed methods, it basically performs some processing and routes the data to a service associated with the data (different data will result in different routing). To ensure that the service runs as quickly as possible, each cycle of receiving, processing and routing of the data is handled by a seperate thread in the threadpool. could this be a problem arising from one thread calling proxyClass.Open()whilst another is already using it? would a lockblock eliminate this problem, if indeed this is the problem?

我想诊断可能需要有关服务的更多信息 - 当服务通过其公开的方法之一接收数据时,它基本上会执行一些处理并将数据路由到与数据关联的服务(不同的数据将导致不同的路由)。为确保服务尽快运行,数据的接收、处理和路由的每个周期都由线程池中的单独线程处理。这可能是一个线程调用proxyClass.Open()而另一个线程已经在使用它而引起的问题吗?将一个lock块消除这一问题,如果确实是这样的问题?

thanks guys, - ive been workikng on this project for toolong, and finally want to see the back of it - but this appears to be the last stumbling block, so any help much appreciated :-)

谢谢大家, - 我在这个项目上工作太久,终于想看看它的背面 - 但这似乎是最后的绊脚石,所以非常感谢任何帮助:-)

=========================================================================

thanks for highlighting that i shouldn't be using the usingconstruct for WCF proxy classes. However the MSDN article isn't the most clearly written piece of literature ever, so one quick question: should i be using a proxy as such:

================================================== ======================

感谢您强调我不应该使用usingWCF 代理类的构造。然而,MSDN 文章并不是有史以来写得最清楚的一篇文献,所以一个简单的问题:我是否应该使用这样的代理:

try
{
    client = new proxy.DataConnectorServiceClient();
    client.Open();
    //do work
    client.Close();
 }
 .................. //catch more specific exceptions
 catch(Exception e)
 {
    client.Abort();
 }

回答by Brian

It definitely sounds like you've called Open() multiple times on the same object.

听起来您确实在同一个对象上多次调用了 Open() 。

回答by mamu

How are you using proxy? Creating new proxy object for each call. Add some code regarding how you use proxy.

你是如何使用代理的?为每次调用创建新的代理对象。添加一些关于如何使用代理的代码。

Desired way of using proxy is for each call you create new proxy and dispose it once completed. You are calling proxy.open() for opened proxy that is wrong. It should be just called once.

使用代理的理想方式是为每次调用创建新代理并在完成后处理它。您正在为错误的打开代理调用 proxy.open() 。它应该只调用一次。

Try using something like below in finally, as wcf does not dispose failed proxy and it piles up. Not sure it would help but give it a shot.

最后尝试使用类似下面的内容,因为 wcf 不会处理失败的代理并且会堆积起来。不确定它会有所帮助,但试一试。

if (proxy.State == CommunicationState.Faulted)
{
    proxy.Abort();
}
else
{
    try
    {
        proxy.Close();
    }
    catch
    {
        proxy.Abort();
    }
}

Why to do this? http://msdn.microsoft.com/en-us/library/aa355056.aspx

为什么要这样做? http://msdn.microsoft.com/en-us/library/aa355056.aspx

Code you posted above would work but you will alway be eating exception. So handle wcf related exception in seperate catch and your generic catch with Excelion would abort then throw exception.

您在上面发布的代码可以工作,但您总是会吃异常。因此,在单独的捕获中处理与 wcf 相关的异常,并且您使用 Excelion 的通用捕获将中止然后抛出异常。

try
{
    ...
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;
}

Also if you still want to use convenience of using statement then you can override dispose method in your proxy and dispose with abort method in case of wcf error.

此外,如果您仍然想使用 using 语句的便利性,那么您可以覆盖代理中的 dispose 方法并在 wcf 错误的情况下使用 abort 方法进行处理。

And do not need to call .Open() as it will open when required with first call.

并且不需要调用 .Open() 因为它会在第一次调用时打开。

回答by Michael Smith

I'm assuming you're using .NET 3.5 or later. In .NET 3.5, the WCF ClientBase'1 class (base class for generated client proxies) was updated to use cached ChannelFactories/Channels. Consequently, unless you're using one of the Client use/creation strategies which disables caching (Client constructor that takes in a Binding object, or accessing one of a few certain properties before the backing channel is created), even though you're creating a new Client instance, it could very well still be using the same channel. In other words, before calling .Open(), always ensure you're checking the .Created status.

我假设您使用的是 .NET 3.5 或更高版本。在 .NET 3.5 中,WCF ClientBase'1 类(生成的客户端代理的基类)已更新为使用缓存的 ChannelFactories/Channels。因此,除非您使用禁用缓存的客户端使用/创建策略之一(接受 Binding 对象的客户端构造函数,或在创建后备通道之前访问一些特定属性之一),即使您正在创建一个新的 Client 实例,它很可能仍在使用相同的通道。换句话说,在调用 .Open() 之前,始终确保您正在检查 .Created 状态。

回答by Wagner Silveira

we hit the same roadblock as you sometime ago.

我们前段时间遇到了和你一样的障碍。

The issue with the using statement , is that if you get to a faulted state, it will still try to close at the end of the block. Another consideration, which was critical for us, is the cost of creating the proxy everytime.

using 语句的问题在于,如果您进入错误状态,它仍会尝试在块的末尾关闭。另一个对我们来说至关重要的考虑因素是每次创建代理的成本。

We learned a lot from those blog posts:

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

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/26/best-practice-always-open-wcf-client-proxy-explicitly-when-it-is-shared.aspx

and

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

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

Hopefuly it will help you as well.

希望它也能帮助你。

Cheers, Wagner.

干杯,瓦格纳。