Pergunta

Alguém sabe de uma implementação fluxo preguiçoso em .net? IOW, eu quero um para criar um método como este:

public Stream MyMethod() {
    return new LazyStream(...whatever parameters..., delegate() {
        ... some callback code.
    });
}

e quando minhas outras chamadas de código de MyMethod () para retornar recuperar o fluxo, ele não vai realmente executar qualquer trabalho até que alguém realmente tenta ler a partir do fluxo. A maneira usual seria fazer MyMethod tomar o parâmetro fluxo como um parâmetro, mas isso não vai funcionar no meu caso (eu quero dar o fluxo retornado a um MVC FileStreamResult).

Para explicar melhor, o que eu estou procurando é para criar uma série de camadas de transformações, de modo

= conjunto de resultados de banco de dados (transformado para) => fluxo de bytes = (encadeado a) => GZipStream = (passada a) => FileStreamResult construtor.

O conjunto de resultados pode ser enorme (GB), então eu não quero para armazenar em cache o resultado em um MemoryStream, o que eu posso passar para o construtor GZipStream. Pelo contrário, eu quero buscar a partir do conjunto de resultados como o GZipStream solicita dados.

Foi útil?

Solução

Esta resposta ( https://stackoverflow.com/a/22048857/1037948 ) links para este artigo sobre como escrever sua própria classe de fluxo.

Para citar a resposta:

O produtor grava dados para o fluxo eo consumidor lê. Há um tampão no assim meio que o produtor pode "write ahead" um pouco. Você pode definir o tamanho do buffer.

Para citar a fonte original:

Você pode pensar no ProducerConsumerStream como uma fila que tem uma interface Stream. Internamente, ele é implementado como um buffer circular. Dois índices acompanhar os pontos de inserção e de remoção no interior do tampão. Bytes são escritos no índice Head, e removido do índice Tail.

Se a cabeça envolve a cauda, ??então o buffer está cheio e o produtor tem que esperar por alguns bytes para ser lido antes que ele possa continuar a escrever. Se cauda alcança com Head, o consumidor tem que esperar por bytes a serem gravados antes que possa prosseguir.

O artigo prossegue para descrever alguns casos estranhos quando os ponteiros envolver em torno, com amostras de código completo.

Outras dicas

A maioria das implementações de fluxo são, por natureza, riachos preguiçosos. Normalmente, qualquer fluxo não vai ler informações de sua origem até que seja solicitado pelo usuário do fluxo (excepto alguns extra "over-leitura" para permitir a amortecer a ocorrer, o que torna o uso de fluxo muito mais rápido).

Seria bastante fácil de fazer uma implementação córrego que fez nenhuma leitura até que seja necessário, substituindo leia para abrir o recurso subjacente e, em seguida, ler a partir dele quando usado, se você precisar de uma implementação de fluxo totalmente preguiçoso. Apenas substituir Read, CanRead, CanWrite e CanSeek.

Em sua classe de fluxo você tem que implementar vários métodos de System.IO.Stream incluindo o método de leitura.

O que você faz neste método é até você. Se você optar por chamar um delegado - isto é com você também, e é claro que você pode passar este delegado como um dos parâmetros do seu construtor. Pelo menos é assim que eu iria fazê-lo.

Infelizmente vai demorar mais do que implementar método de leitura, e o delegado não cobrirá outros métodos necessários

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top