2009-08-17 38 views
1

我在IIS中使用basicHttpBinding使用流模式託管WCF服務。 WCF Web服務通過使用ADO.Net查詢後端SQL Server 2008,並將DataTable返回給WCF服務的客戶端。WCF流模式問題

我的WCF流模式是理解,

  1. WCF流模式應該使用在客戶端和服務器端的唯一不變的數量的內存;
  2. WCF流模式應該能夠在客戶端和服務器之間傳輸任意數量的數據。

我的理解是否正確?

如果是的話,我下面的示例打破這兩個規則,我觀察到兩種違法行爲,

  1. 我發現我下面的示例繼續吃內存(從任務管理器,內存使用量增加的性能選項卡)。我在同一臺機器上運行客戶端和服務器。那麼,WCF流媒體模式不會使用恆定數量的內存?

  2. 當傳輸10M行的一個DataTable時,下面有異常發佈。但傳輸1M行很好。那麼,WCF流媒體模式不能傳輸任何數量的數據?

任何想法是什麼錯?

異常消息:在接收到 http://labmachine1/service.svc的 HTTP響應

發生錯誤。這個 可能是由於服務端點 綁定不使用HTTP協議。 這也可能是由於HTTP 請求上下文被 服務器中止(可能歸因於服務 關閉)。有關更多詳細信息,請參閱服務器日誌 。

{「基礎連接已經關閉:發生意外的錯誤 接收。」}

這裏是我的服務器端的整個源代碼,在web.config中的服務器I宿主,換不換默認值。由於我在IIS中託管,我正在使用basicHttpBinding。

public class StudentManagement : IStudentManagement 
{ 
    public DataTable Poll(int Id) 
    { 
     return MakeParentTable(); 
    } 

    private DataTable MakeParentTable() 
    { 
     // Create a new DataTable. 
     System.Data.DataTable table = new DataTable("ParentTable"); 
     // Declare variables for DataColumn and DataRow objects. 
     DataColumn column; 
     DataRow row; 

     // Create new DataColumn, set DataType, 
     // ColumnName and add to DataTable.  
     column = new DataColumn(); 
     column.DataType = System.Type.GetType("System.Int32"); 
     column.ColumnName = "id"; 
     column.ReadOnly = true; 
     column.Unique = true; 
     // Add the Column to the DataColumnCollection. 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = System.Type.GetType("System.String"); 
     column.ColumnName = "ParentItem"; 
     column.AutoIncrement = false; 
     column.Caption = "ParentItem"; 
     column.ReadOnly = false; 
     column.Unique = false; 
     // Add the column to the table. 
     table.Columns.Add(column); 

     // Make the ID column the primary key column. 
     DataColumn[] PrimaryKeyColumns = new DataColumn[1]; 
     PrimaryKeyColumns[0] = table.Columns["id"]; 
     table.PrimaryKey = PrimaryKeyColumns; 

     // Create three new DataRow objects and add 
     // them to the DataTable 
     for (int i = 0; i <= 10000000; i++) 
     { 
      row = table.NewRow(); 
      row["id"] = i; 
      row["ParentItem"] = "ParentItem " + i; 
      table.Rows.Add(row); 
     } 

     return table; 
    } 
} 

客戶端代碼:

static void Main(string[] args) 
{ 
    StudentIdentifier identifier = new StudentIdentifier(); 
    identifier.Id = 100; 
    StudentManagementClient client = new StudentManagementClient(); 

    DataTable student = client.Poll(identifier); 

    Console.WriteLine(student.Rows.Count); 
} 

對客戶端的app.config流模式配置,

<basicHttpBinding> 
     <binding name="BasicHttpBinding_IStudentManagement" closeTimeout="00:01:00" 
     openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00" 
     allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
     maxBufferSize="1500000000" maxBufferPoolSize="1500000000" maxReceivedMessageSize="1500000000" 
     messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed" 
     useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="1500000000" maxStringContentLength="1500000000" 
      maxArrayLength="1500000000" maxBytesPerRead="1500000000" maxNameTableCharCount="1500000000" /> 
     <security mode="None"> 
      <transport clientCredentialType="None" proxyCredentialType="None" 
      realm="" /> 
      <message clientCredentialType="UserName" algorithmSuite="Default" /> 
     </security> 
     </binding> 
    </basicHttpBinding> 

服務器端的web.config的流模式,

<basicHttpBinding> 
    <binding name="BasicHttpBinding_IStudentManagement" closeTimeout="00:01:00" 
     openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00" 
     allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
     maxBufferSize="1000000000" maxBufferPoolSize="1000000000" maxReceivedMessageSize="1000000000" 
     messageEncoding="Mtom" textEncoding="utf-8" transferMode="Streamed" 
     useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="32" maxStringContentLength="1000000000" maxArrayLength="1000000000" 
      maxBytesPerRead="4096" maxNameTableCharCount="16384" /> 
     <security mode="None"> 
     <transport clientCredentialType="None" proxyCredentialType="None" 
      realm="" /> 
     <message clientCredentialType="UserName" algorithmSuite="Default" /> 
     </security> 
    </binding> 
    </basicHttpBinding> 

回答

0

maxB ufferSize屬性約束了WCF在發送/接收流式數據時使用的內存量。但是,在將大對象發送到客戶端之前,您正在將大對象加載到內存中。

我會首先建議您使用DTO(數據傳輸對象)將數據發送給客戶端,並且如果您需要將大量數據發送到客戶端,那麼您將實現分頁機制以便以可管理的塊傳輸數據。

從理論上講,您可以使用WCF向客戶端發送1000萬條記錄,實際上,客戶端幾乎不需要一次性處理那麼多的數據。

1

在流模式下,您必須使用system.io.stream作爲返回類型或參數類型。顯然,你沒有這樣做。