Streaming com WCF e MTOM

Eu estou usando ligações do WCF com o modo de transferência em fluxo, para upload e download de conteúdo binário de / para um serviço. Eu consegui fazer funcionar. Vou incluir a configuração, contratos, etc para referência.

Fiz alguns testes para comparar diferentes vinculações e codificações. O upload de resultados parece ok. O NetTcp é o mais rápido, seguido pelo BasicHttp-MTOM e pelo BasicHttp-Text. O que me surpreende é que, ao baixar arquivos grandes, o MTOM é muito lento, ao contrário da codificação de texto com BasicHttp e codificação binária com o NetTcp.

Estou esquecendo de algo? Por que o BasicHttp-MTOM funciona de maneira mais lenta que outras ligações ao fazer o upload? Além disso, implementei buffer duplo para downloads. Isso também funciona bem com todas as ligações, exceto BasicHttp com codificação MTOM. Por que o buffer duplo não ajuda ao usar o MTOM?

Obrigado pela leitura, seus conselhos e idéias sobre isso.

Resultado dos testes:

Upload de dados binários de 150 MB para o serviço. Cliente cria um fluxo de arquivo de um arquivo de 150 MB e passa para o servidor. O servidor lê o fluxo em um fluxo de memória. Nenhum buffer duplo ainda. Os resultados parecem rápidos, pois não há gravação de dados no sistema de arquivos. E as ligações executam conforme o esperado.

Download de dados binários de 100 MB de serviço. Serviço cria um fluxo de memória e passa para o cliente. Cliente grava no sistema de arquivos. Aqui estão os resultados com buffer único e duplo. Como você pode ver, o MTOM parece extremamente lento e também não responde ao buffer duplo.

Configuração do servidor (omitiu algumas partes para simplificar):

<configuration>
  <system.web>
    <httpRuntime maxRequestLength="2147483647"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="StreamedNetTcpBinding"
                 transferMode="Streamed"
                 maxReceivedMessageSize="1099511627776">
        </binding>
      </netTcpBinding>
      <basicHttpBinding>
        <binding name="StreamedBasicHttpBindingWithMtom"
                 messageEncoding="Mtom" transferMode="Streamed"
                 maxReceivedMessageSize="1099511627776">
        </binding>
        <binding name="StreamedBasicHttpBinding"
                 transferMode="Streamed"
                 maxReceivedMessageSize="1099511627776">
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Configuração do cliente (deixada de fora algumas partes para simplificar):

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="StreamedBasicHttpBindingWithMtom" 
                 maxReceivedMessageSize="1099511627776"
                 messageEncoding="Mtom" transferMode="Streamed">
        </binding>
        <binding name="StreamedBasicHttpBinding"
                 maxReceivedMessageSize="1099511627776"
                 transferMode="Streamed">
        </binding>
      </basicHttpBinding>
      <netTcpBinding>
        <binding name="StreamedNetTcpBinding" transferMode="Streamed"
          maxReceivedMessageSize="1099511627776">
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

Contrato de serviço:

[ServiceContract]
public interface IFileService
{
    [OperationContract]
    void UploadFile(DocumentData document);

    [OperationContract]
    DocumentData DownloadFile();
}

Contrato de mensagem:

[MessageContract]
public class DocumentData
{
    [MessageHeader(MustUnderstand = true)]
    public string DocumentName { get; set; }

    [MessageHeader(MustUnderstand = true)]
    public int FileLength { get; set; }

    [MessageBodyMember(Order = 1)]
    public Stream Data { get; set; }
}

Edit: Isso acabou por ser um problema com a minha configuração do ambiente de desenvolvimento no trabalho. Quando fiz os mesmos testes em casa, os resultados foram os esperados.

questionAnswers(1)

yourAnswerToTheQuestion