2011-11-22 39 views
20

我在WCF中創建了一個Web服務,該服務返回每行有10個數據的54000多個數據行。我已經使用wsHttpBinding進行通信。該服務在數據較少(即2000行)的情況下工作良好,但當嘗試發送50000行(〜2MB)的大型記錄集時,該服務會彈出。異常消息是這樣的在WCF服務中傳輸大量數據

接收到對http://localhost:9002/MyService.svc的HTTP響應時發生錯誤。這可能是由於服務端點綁定不使用HTTP協議。這也可能是由於HTTP請求上下文被服務器中止(可能是由於服務關閉)。查看服務器日誌獲取更多詳細信

請不要告訴我在客戶端使用分頁 - 我知道它會解決問題。但是我需要客戶端的整個數據塊。在服務器

我的服務配置是

<system.serviceModel> 
    <bindings> 
    <wsHttpBinding> 
     <binding name="MyWsHttpBinding" /> 
    </wsHttpBinding> 
    </bindings> 
    <services> 
    <service name="AdminService"> 
     <endpoint address="AdminSrv" 
       binding="wsHttpBinding" 
       contract="IAdminService"/> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     <host> 
     <baseAddresses> 
      <add baseAddress="/Bus/IRfotoWCF" /> 
     </baseAddresses> 
     </host> 
    </service> 
    </services> 
    <behaviors> 
    <serviceBehaviors> 
     <behavior> 
     <!-- To avoid disclosing metadata information, 
        set the value below to false and remove the metadata endpoint above before deployment --> 
     <serviceMetadata httpGetEnabled="True"/> 
     <!-- To receive exception details in faults for debugging purposes, 
        set the value below to true. Set to false before deployment 
        to avoid disclosing exception information --> 
     <serviceDebug includeExceptionDetailInFaults="True" /> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment> 
</system.serviceModel> 

我的客戶端配置是

<system.serviceModel> 
    <bindings> 
    <basicHttpBinding> 
     <binding name="BasicHttpBinding_IAdminService" closeTimeout="00:01:00" 
       openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
       allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
       maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" 
       messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
       useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" 
         maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
     <security mode="None"> 
      <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> 
      <message clientCredentialType="UserName" algorithmSuite="Default" /> 
     </security> 
     </binding> 
    </basicHttpBinding> 
    </bindings> 
    <client> 
    <endpoint address="http://localhost/TestService/AdminService.svc" 
       binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAdminService" 
       contract="IAdminService" name="BasicHttpBinding_IAdminService" /> 
    </client> 
</system.serviceModel> 

會有人幫助我無論是在客戶端和服務器端的配置excact。即使我需要更改綁定從wsHttpBindingnetTcpBinding - 我沒有這樣做的問題。提前致謝。

回答

33

經過大量調查,我得到了解決方案。其實很多事情都需要改變。

以下更改需要在服務器端中完成。

首先我只好一個的maxRequestLength的httpRuntime元素設置爲一個較大的值來運行較長時間的請求。

<system.web>  
<httpRuntime maxRequestLength="102400" /> 
</system.web> 

我介紹NetTcpBinding的 binnding與maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize2147483647一個較大的值自定義更改。

<binding name="myNetTcpBinding" 
maxBufferPoolSize="2147483647" 
maxBufferSize="524288" 
maxReceivedMessageSize="2147483647"> 

同時在serviceBehaviorsendpointBehaviors像波紋管的加入maxItemsInObjectGraph(不要忘了提到在serviceendpoint節點的行爲名稱)

<behaviors> 
     <serviceBehaviors>   
     <behavior name="myNetTcpBehaviour"> 
      <serviceMetadata httpGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="myNetTcpEndPointBehaviour"> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 

最後我的服務器配置如下像這樣

<system.web>  
    <httpRuntime maxRequestLength="102400" /> 
</system.web> 


    <system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
     <binding name="MyWsHttpBinding" /> 
     </wsHttpBinding> 
     <netTcpBinding> 
     <binding name="myNetTcpBinding" 
       closeTimeout="00:01:00" 
       openTimeout="00:01:00" 
       receiveTimeout="00:10:00" 
       sendTimeout="00:01:00" 
       transactionFlow="false" 
       transferMode="Buffered" 
       transactionProtocol="OleTransactions" 
       hostNameComparisonMode="StrongWildcard" 
       listenBacklog="10" 
       maxBufferPoolSize="2147483647" 
       maxBufferSize="524288" 
       maxConnections="10" 
       maxReceivedMessageSize="2147483647"> 
      <readerQuotas maxDepth="32" 
         maxStringContentLength="8192" 
         maxArrayLength="16384" 
         maxBytesPerRead="4096" 
         maxNameTableCharCount="16384" /> 
      <reliableSession ordered="true" 
          inactivityTimeout="00:10:00" 
          enabled="false" /> 
      <security mode="Transport"> 
      <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> 
      </security> 
     </binding> 
     </netTcpBinding> 
    </bindings> 
    <services> 
     <service name="AdminService" behaviorConfiguration="myNetTcpBehaviour"> 
     <endpoint address="AdminSrv" 
        binding="netTcpBinding" 
        bindingConfiguration="myNetTcpBinding" 
        contract="IAdminService" 
        behaviorConfiguration="myNetTcpEndPointBehaviour"/> 

     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
     <host> 
      <baseAddresses> 
      <add baseAddress="/Bus/IRfotoWCF" /> 
      </baseAddresses> 
     </host> 
     </service> 
    <behaviors> 
     <serviceBehaviors>   
     <behavior name="myNetTcpBehaviour"> 
      <serviceMetadata httpGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="myNetTcpEndPointBehaviour"> 
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"></serviceHostingEnvironment> 
    </system.serviceModel> 

現在在客戶端 configuratioin您需要更改maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"

還需要在終結點行爲配置中添加maxItemsInObjectGraph="2147483647"仍有很多 -

 <endpointBehaviors> 
      <behavior name="myEndPointBehavior"> 
       <dataContractSerializer maxItemsInObjectGraph="2147483647" /> 
      </behavior> 
     </endpointBehaviors> 

現在我可以內5.30分鐘其中查詢執行,持續10秒,因此傳輸時間是5.20分鐘發送行。

歡迎評論和任何改進建議。

+0

我不明白。這是一個非常好的解決方案,當一個服務在5.20分鐘內等待另一個服務時。我認爲這是關於建築的一個大問題,但我找不到解決方案。 – Vladislav

+0

我繼續用傳輸大數據測試速度。使用「Chunks」方法,我可以發送300 000(!)行,在4.34分鐘內將其保存到數據庫,而不會對我的服務配置做任何更改。我只是將我的數據分爲50行的塊。 – Vladislav

+0

您應該使用Datacontract Serializer代替XML。這是迄今爲止reference.cs中的手動替換作業。 – NickD

1

如果您查看綁定詳細信息,它們不會完全匹配服務器和客戶端的匹配。 maxBufferSize, maxBufferPoolSize, maxReceivedMessageSize的屬性也將在服務器端定義。然後你需要根據你正在查看的大小來設置值。

+0

我已經嘗試這些maxBufferSize,maxBufferPoolSize,maxReceivedMessageSize與值2147483647都在服務器端和客戶端。仍然是例外。 –

+0

我無法在您的帖子中看到配置文件中的設置。你確定綁定配置設置正確嗎? – Kangkan

+0

Yap,我在服務器和客戶端的本地配置綁定配置中。但是現在我已經解決了這個問題 - 請看答案。無論如何,謝謝你隨時評論答案。 –

-3

使用用戶定義的表類型(如果您使用的是SQL),而不是使用for循環遍歷WCF處理龐大的數據。它會將時間從6分鐘縮短到15-20秒。

+0

只是...... ......? – Gareth