1

アプリケーションにある単一のWcfサービスで問題が発生しています。その中には約150の[OperactionContract]があります。VisualStudio2008内でサービス参照を更新できなくなりました。

アップデートを呼び出そうとすると、「ソケットが強制的に閉じられました」から「無効なタイプ」まで、さまざまな種類の奇妙なエラーやその他の奇妙なメッセージが表示されます。10〜20の操作をコメントアウトすると、正常に機能します。

私はここ、MSDN、および多くのブログであらゆる種類の投稿を読みました。これらはすべて、メインバインディングまたはMetadataExchangeバインディングのいずれかで変更する必要のあるバインディング構成を指します。

私の問題は、これらすべてを試したが、まだ確実に機能させていないことです。

私はアプリケーションでサービスを自己ホスティングしており、その同じアプリケーションがクライアントでもあります。Wcfサービスレイヤーを介してアプリケーションを2つに分割している最中であるため、これらは(現在)同じ構成ファイルを共有しています。

これが私が定義した私のバインディングを示す抜粋です:

<system.serviceModel>

    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_IRhinoServices"
                 closeTimeout="00:05:00"
                 openTimeout="00:05:00"
                 receiveTimeout="00:15:00"
                 sendTimeout="00:05:00"
                 transactionFlow="false"
                 transferMode="Buffered"
                 transactionProtocol="OleTransactions"
                 hostNameComparisonMode="StrongWildcard"
                 listenBacklog="100"
                 maxBufferPoolSize="2147483647"
                 maxBufferSize="2147483647"
                 maxConnections="100"
                 maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647"
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />
          <reliableSession ordered="true"
                           inactivityTimeout="00:10:00"
                           enabled="false" />
          <security mode="None">
          </security>
        </binding>
      </netTcpBinding>

      <customBinding>
        <binding name="customMex">
          <textMessageEncoding>
            <readerQuotas maxDepth="2147483647"
                          maxStringContentLength="2147483647"
                          maxArrayLength="2147483647"
                          maxBytesPerRead="2147483647"
                          maxNameTableCharCount="2147483647" />
          </textMessageEncoding>
          <tcpTransport transferMode="Buffered"
                        maxReceivedMessageSize="2147483647"
                        maxBufferSize="2147483647"/>
        </binding>
      </customBinding>

    </bindings>

    <client>
      <endpoint address="net.tcp://localhost:8523/RhinoServices"
                binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IRhinoServices"
                contract="RhinoServicesReference.IRhinoServices"
                name="NetTcpBinding_IRhinoServices">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>

    <services>
      <service behaviorConfiguration="CounterSketchServer.RhinoServicesBehavior"
               name="CounterSketchServer.RhinoServices">
        <endpoint address=""
                  binding="netTcpBinding"
                  contract="CounterSketchServer.IRhinoServices">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>

        <endpoint address="mex"
                  binding="customBinding"
                  contract="IMetadataExchange"
                  name=""
                  bindingConfiguration="customMex"
                  listenUriMode="Explicit" />

        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8523/RhinoServices" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="CounterSketchServer.RhinoServicesBehavior">
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

この不思議な限界に達するまで、この2週間はうまく機能していたUpdate Service Referenceをクリックして、プロキシクラスを生成できるようにする必要があります。

mexのhttpバインディングについてのこの話を解決するために私が見た例のほとんどですが、私はセルフホスティングなので、可能であればnetTcpだけを使い続けたいと思います。

誰か助けてくれませんか?

ありがとうございました。

* アップデート *

@Aliostadの提案を試しましたが、最初はうまく機能しているように見えました。UI要素を更新するWcf呼び出しのいくつかを試すまでは。これらは、Visual Studios(サービス参照の追加)ツールによって生成されたプロキシクラスでNetTCPバインディングを使用するときにたまたま機能しました。ただし、チャネルファクトリを使用する場合は機能しません。

JuvalのWCF本でSyncrhonizationContextを調べてみましたが、何も機能していないようです。

ChannelFactoryを使用して作成するチャネルのバインディングとして名前付きパイプとNetTCPの両方を使用しようとしましたが、長時間実行されるWcf操作に関連して、これらは互いに非常に異なる動作をするように見えますが、どちらもUI要素を更新するためには機能しません。

私のサービスは実際にはRhino3DCADエンジンのプラグインで実行されており、セラチン呼び出し(Renderなど)によってRhinoのUIが更新されます。これがスレッド境界の問題を引き起こしていると思います。私が受け取る例外は次のとおりです。 保護されたメモリの読み取りまたは書き込みを試みました

このシナリオでChannelFactoryメソッドを効果的に使用したり、特定のWcfクラスの操作が多すぎてサービスプロキシを生成できないという問題を修正したりするための提案があれば、ぜひご協力ください。

ありがとう!

4

2 に答える 2

2

まず、唯一の解決策は、参照を削除して、再度追加することだと思います。


または、クライアントとサービスの両方を所有している場合(質問を読んだことから得られるようです)、サービス参照を使用する代わりに、サービスインターフェイスをクライアントと共有することを強くお勧めしますか?

これは、クライアントとサーバーの両方を所有している場合に間違いなく推奨されるアプローチです(そして、発生しているすべての問題からあなたを救うでしょう)。クライアントを所有していない場合も、エンティティ/dtoを共有するだけでよいと思います。インターフェイス。

これには、次のことが必要です。

  • エンティティ/dtos用のクラスライブラリプロジェクトを作成します。クライアントと共有します。
  • サービスインターフェイス用のクラスライブラリプロジェクトを作成します。クライアントと共有します。
  • サービス実装用のクラスライブラリプロジェクトを作成します。サーバー上にのみとどまります。
  • クライアントはChannelFactory<T>、ファクトリを作成してから、を呼び出してプロキシを作成するために使用しますCreateChannel()
于 2011-04-13T22:00:58.107 に答える
1

SvcUtil.exeとVisualStudio2008の両方からUpdateServiceReferenceが再び機能するようになりました。

そのために、devenv.exe.configSvcUtil.exe.configの両方の構成ファイルに次のセクションを追加しました。

<!-- CUSTOM MetaDataExchaning Binding to all for LARGE WCF Services -->

<client>
    <endpoint name="net.tcp" binding="netTcpBinding" bindingConfiguration="GenericBinding"
    contract="IMetadataExchange" />
    <endpoint name="http" binding="wsHttpBinding" bindingConfiguration="SecureBinding" contract="IMetadataExchange" />
</client>

<bindings>

    <netTcpBinding>
        <binding name="GenericBinding" maxBufferPoolSize="2147483647"
        maxReceivedMessageSize="2147483647" >
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
            maxArrayLength="2147483647" maxBytesPerRead="2147483647"
            maxNameTableCharCount="2147483647" />
            <security mode="None"/>
        </binding>
    </netTcpBinding>

    <wsHttpBinding>
        <binding name="SecureBinding" maxBufferPoolSize="2147483647"
        maxReceivedMessageSize="2147483647" >
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
            maxArrayLength="2147483647" maxBytesPerRead="2147483647"
            maxNameTableCharCount="2147483647" />
            <security mode="Message">
                <transport clientCredentialType="Windows" />
            </security>
        </binding>
    </wsHttpBinding>
</bindings>

次に、アプリケーションサーバープラグインで、まだプログラムでServiceHostを作成しているので、メタデータ交換を有効にするために別のエンドポイントを追加しました。

        // DATA ENDPOINT
        NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport, true);
        Uri baseAddress = new Uri("net.tcp://localhost:8555/RhinoServices");
        _rhinoServicesHost = new ServiceHost(typeof(RhinoServices), baseAddress);
        _rhinoServicesHost.AddServiceEndpoint(typeof(IRhinoServices), binding, baseAddress);

        // META ENDPOINT
        BindingElement bindingElement = new TcpTransportBindingElement();
        CustomBinding customBinding = new CustomBinding(bindingElement);
        ServiceMetadataBehavior metadataBehavior = _rhinoServicesHost.Description.Behaviors.Find<ServiceMetadataBehavior>();
        if (metadataBehavior == null)
        {
            metadataBehavior = new ServiceMetadataBehavior();
            _rhinoServicesHost.Description.Behaviors.Add(metadataBehavior);
        }
        _rhinoServicesHost.AddServiceEndpoint(typeof(IMetadataExchange), customBinding, "MEX");

        _rhinoServicesHost.Faulted += RhinoServicesHost_Faulted;
        _rhinoServicesHost.Open();

契約数に関係なく、参照を更新できるようになりました。

ただし、このプロセス全体で、この方法に切り替えてから発生した保護されたメモリエラーの読み取りまたは書き込みの試行が解消されていないことを認める必要があります。

だから私はまだそれを追跡する必要があると思います...

また、@ trendlが回答した別の質問(クリックして表示)でこの解決策を見つけました。ご協力ありがとうございました。

于 2011-04-15T17:31:13.303 に答える