WCF 无法用于通信,因为它处于故障状态

Posted

技术标签:

【中文标题】WCF 无法用于通信,因为它处于故障状态【英文标题】:WCF Cannot be used for communication because it is in the Faulted state 【发布时间】:2012-03-13 15:19:46 【问题描述】:

当我尝试使用网络服务时,我得到以下异常。我的主要问题是这个异常什么时候发生?在服务器还是客户端?错误在哪里?服务器是否会因各种故障而抛出此错误?

我自己做了一些似乎有效的更改

它现在确实有效。我在服务客户端上删除了 using 并添加了 som cleanup。

if (Service != null && Service.State != CommunicationState.Faulted)
                
                    success = true;
                    Service.Close();
                

            
            catch (Exception ex)
            
                msg = "Error" + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace;
            
            finally
                if (!success)
                
                    if (Service != null) Service.Abort();
                
            

这是个例外:

The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.

Server stack trace: 
at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)

Exception rethrown at [0]: 
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
 at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.ClientBase`1.System.ServiceModel.ICommunicationObject.Close(TimeSpan timeout)
at System.ServiceModel.ClientBase`1.Close()
at System.ServiceModel.ClientBase`1.System.IDisposable.Dispose()
at bNet.Services.Customers.Cres.Helios.ServiceForm.Send(ServiceFormAction task) in C:\bNetProjects\bNet Web Tools\Solution root\bNet.Services\Customers\Cres\Helios\ServiceForm.cs:line 99
at bNet.Web.Sites.Public.Customers.Cres.ServiceSkjema.Units.Page.ServiceFormControl.SubmitFormClick(Object sender, EventArgs e) in C:\bNetProjects\bNet Web Tools\Solution root\bNet.Web.Sites.Public\Customers\Cres\ServiceSkjema\Units\Page\ServiceFormControl.ascx.cs:line 192
at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

【问题讨论】:

异常调用栈其实告诉你很多必须注意的事情。例如,Dispose 调用 Close。因此,如果代理已经处于故障状态,则只能调用 Abort,不能调用 Close 或 Dispose。幸运的是,您发现了必要的更改。微软其实有一篇很好的文章强调推荐什么样的调用模式,msdn.microsoft.com/en-us/library/aa355056.aspx 也请看这里***.com/questions/2763592/… 也得到了这个异常,不是因为异常处理,而是因为试图在没有设置TableName 的情况下返回DataTable。见***.com/questions/12702/… The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication的可能重复 【参考方案1】:

故障状态表示服务器端出现意外异常。在之前的电话中。

您也应该在客户端遇到异常,也许您的代码忽略了它?

您可以通过重新打开连接来解决它。但您似乎需要更好的错误处理。

【讨论】:

我做了一些改变自己,完成了这项工作。谢谢你的回答。【参考方案2】:

而不是使用using 语句,尝试在没有它的情况下运行您的代码。

来自

using(var client = new WCFClient())

    // ... code

var client = new WCFClient()

// ... code

这样做后,我们可以看到原始 WCF 无法用于通信,因为它处于故障状态消息是由 using() 调用本身引起的。 为什么? 我们使用 WCF 客户端的代码传递了无效的凭据,服务器以错误响应并将代理的状态更改为故障。 using() 块 as we know 在对象上调用 Dispose() - 在本例中是我们的 WCF 客户端。

由于WCF客户端失败,并且WCF客户端处于故障状态,调用Dispose()导致抛出WCF无法用于通信,因为它处于故障状态错误。

我们可以通过将使用 WCF 客户端的代码包装在 try...catch 块中来看到这一点。

【讨论】:

感谢@Zac,删除 using 帮助我们捕获了适当的异常,恰好是:“未提供客户端证书。在 ClientCredentials 中指定客户端证书。”。似乎删除 using 应该是获得确切异常而不是泛型的第一件事:“通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信,因为它处于故障状态。”【参考方案3】:

此错误也可能是由于使用 OperationContract 属性标记的方法为零。这是我在构建新服务并进行长期测试时遇到的问题。

【讨论】:

以上是关于WCF 无法用于通信,因为它处于故障状态的主要内容,如果未能解决你的问题,请参考以下文章

通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信,因为它处于故障状态

如何确保您没有收到 WCF 故障状态异常?

WCF 通道故障状态是不是有帮助?

用于进程间通信的 wcf 服务

WCF入门教程五[WCF的通信模式]

System.ServiceModel.CommunicationObjectFaultedException