WCF:StackoverFlow异常

时间:2010-12-15 13:33:02

标签: c# .net vb.net wcf

我在尝试服务.NET ServiceController类时遇到异常。当它为null时序列化很好但是一旦我填充它我得到一个stackoverflow异常。

这样可行:

    [DataMember]
    public ServiceController MyServiceController
    {
        get { return null; }
    }

但是这会给出错误“System.ServiceProcess.dll中出现类型'System.StackOverflowException'的未处理异常”:

public class TestClass
{
    private ServiceController _serviceController;
    [DataMember]
    public ServiceController MyServiceController
    {
        get { return ServiceController.GetServices()[0];
    }
}

奇怪的是,日志中根本没有错误。当出现错误时我可以在日志中看到它,所以不是因为我的日志不能正常工作。这是我的配置文件

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyCompany.Wcf.RdbmsServer.RdbmsServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="MyCompany.Wcf.RdbmsServer.RdbmsServiceBehavior"
        name="MyCompany.Wcf.RdbmsServer.RdbmsService">
        <endpoint address="" binding="wsHttpBinding" contract="MyCompany.Wcf.RdbmsServer.IRdbmsService" bindingConfiguration="IncreaseMaxMessageSize">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8731/Design_Time_Addresses/MyCompany.Wcf.RdbmsServer/RdbmsService/" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <bindings>
      <wsHttpBinding>
        <binding name="IncreaseMaxMessageSize" 
            maxReceivedMessageSize="655360000">
        </binding>
      </wsHttpBinding>
    </bindings>
  </system.serviceModel>

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel"
              switchValue="All"
              propagateActivity="true">
        <listeners>
          <add name="traceListener"
              type="System.Diagnostics.XmlWriterTraceListener"
              initializeData= "c:\Traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

</configuration>

这是我的服务界面

[ServiceContract]
public interface IRdbmsService
{
    [OperationContract]
    TestClass GetServiceControllerList();
}

实施是:

    public TestClass GetServiceControllerList()
    {
       return new TestClass();
    }

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您导致序列化程序递归:

public class TestClass
{
    private ServiceController _serviceController;
    [DataMember]
    public ServiceController MyServiceController
    {
        get { return ServiceController.GetServices()[0]; // <-- this returns your service
    }
}

返回的服务是IRdbmsService,返回TestClass。然后需要序列化等等。

修改:澄清:

当序列化TestClass时,序列化程序会查看其所有DataMember属性,其中一个属性为ServiceController。然后它会序列化此属性,该属性在get

上执行此操作
return ServiceController.GetServices()[0];

由于IRdbmsService是作用域中定义的唯一服务,因此它位于GetServices调用响应的索引0处,因此必须将其序列化。由于GetServiceControllerList的返回类型为TestClass,因此必须序列化TestClass,这会将我们带回到开头(因此,递归)。

至于如何解决这个问题,取决于你想要做什么。这项服务目前正在做的是将自己的信息返回给来电者,这对我来说没有意义;呼叫者在消费时已经有这些信息(在打电话之前)。你能澄清一下你的意图吗?

答案 1 :(得分:0)

是的,在ServiceController CLASS的构造函数中,你可能正在调用一些没有条件停止的递归,所以每次调用递归的东西时,程序都会推送到堆栈,正如我所说的那样,没有停止条件,它将添加到堆栈,直到内存爆炸,因此它给出了这个错误名称StackOverFlow。

建议:添加一个断点来调试其调用递归的位置。调试时很容易。