2009-08-17 3 views
1

Я использую службу WCF в IIS, используя basicHttpBinding, используя потоковый режим. Веб-службы WCF запрашивают SQL Server 2008 с помощью ADO.Net и возвращают DataTable на клиентскую сторону службы WCF.Проблема с потоковым режимом WCF

Мое понимание потокового режима WCF являются,

  1. WCF потоковый режим следует использовать только постоянное количество памяти на стороне клиента, так и серверной части;
  2. Режим потоковой передачи WCF должен иметь возможность передавать любое количество данных между клиентом и сервером.

Правильно ли я понимаю?

Если да, то мой следующий пример разорвать эти два правила, я наблюдаю два нарушения,

  1. я нахожу мой следующий пример продолжает есть память (на вкладке производительности диспетчера задач, увеличивается использование памяти). Я запускаю как клиент, так и сервер на одном компьютере. Итак, режим потоковой передачи WCF не использует постоянный объем памяти?

  2. при передаче 10M строк DataTable, есть исключение, размещенное ниже. Но передача 1M строк в порядке. Таким образом, режим потоковой передачи WCF не может передавать какое-либо количество данных?

Любые идеи, что не так?

Сообщение об исключении:

при получении ответа HTTP к http://labmachine1/service.svc произошла ошибка. Этот может быть связан с привязкой конечной точки службы , не использующей протокол HTTP. Это также может быть связано с тем, что контекст HTTP прерывается сервером (возможно, из-за отказа службы ). См. Журналы сервера для .

{ «Базовое соединение закрыто: Непредвиденная ошибка на прием.»}

Вот весь мой исходный код стороны сервера, для сервера I хоста в web.config, никаких изменений для значения по умолчанию. Поскольку я принимаю в 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); 
} 

Streaming Конфигурация режима для клиентской стороны 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

Макс. Атрибут ufferSize - это то, что ограничивает объем памяти WCF при отправке/получении потоковых данных. Однако вы загружаете большие объекты в память перед отправкой их клиенту.

Я бы порекомендовал сначала использовать DTO (перенос данных) для отправки ваших данных клиенту, и если вам нужно отправить столько данных клиенту, что вы реализуете механизм подкачки для передачи данных в управляемые куски ,

В теории вы можете использовать WCF для отправки 10 миллионов записей клиенту, на практике клиенты вряд ли когда-либо нуждаются в таких данных, особенно все сразу.

1

В режиме потока вам необходимо использовать system.io.stream в качестве типа возврата или типа параметра. очевидно, вы этого не делаете.

Смежные вопросы