Compartilhar via


streamWriterBufferedDataLost MDA

O streamWriterBufferedDataLost Assistente de depuração gerenciada (MDA) é ativado quando uma StreamWriter é gravado, mas o Flush ou Close método subseqüentemente não foi chamado antes que a instância da StreamWriter é destruída. Quando este MDA está habilitado, o tempo de execução determina se quaisquer dados no buffer ainda dentro do StreamWriter. Se existirem um buffer de dados, o MDA é ativado. Chamar o Collect e WaitForPendingFinalizers métodos podem forçar os finalizadores para executar. Caso contrário, finalizadores serão executado em momentos arbitrários aparentemente e possivelmente nenhuma na saída do processo. Executando explicitamente os finalizadores com este MDA habilitado ajudará a forma mais confiável reproduzir esse tipo de problema.

Sintomas

A StreamWriter não gravar o último 1 a 4 KB de dados para um arquivo.

Causa

O StreamWriter buffers de dados internamente, que requer que o Close ou Flush método ser chamado para gravar os dados em buffer para o armazenamento de dados subjacente. Se Close ou Flush não é adequadamente chamada, os dados armazenados em buffer na StreamWriter instância não pode ser gravada como esperado.

A seguir é um exemplo de código mal escrito que este MDA deve capturar.

// Poorly written code.
void Write() 
{
    StreamWriter sw = new StreamWriter("file.txt");
    sw.WriteLine("Data");
    // Problem: forgot to close the StreamWriter.
}

O código anterior ativará este MDA mais confiável se uma coleta de lixo é disparada e, em seguida, suspenso até os finalizadores tenham terminado. Para rastrear esse tipo de problema, você pode adicionar o seguinte código ao final do método anterior em uma compilação de depuração. Isso ajudará a ativar de forma confiável o MDA, mas obviamente não corrigir a causa do problema.

    GC.Collect();
    GC.WaitForPendingFinalizers();

Resolução

Certificar-se de que você chamar Close ou Flush sobre o StreamWriter antes de fechar um aplicativo ou qualquer bloco de código tem uma instância de um StreamWriter. Um dos melhores mecanismos para atingir isso é criar a instância com um C# using bloco (Using em Visual Basic), que garantirá a Dispose método para o gravador é invocado, o que resulta na instância que está sendo fechada corretamente.

using(StreamWriter sw = new StreamWriter("file.txt")) 
{
    sw.WriteLine("Data");
}

O seguinte código mostra a mesma solução, usando try/finally em vez de using.

StreamWriter sw;
try 
{
    sw = new StreamWriter("file.txt"));
    sw.WriteLine("Data");
}
finally 
{
    if (sw != null)
        sw.Close();
}

Se nenhuma dessas soluções pode ser usada (por exemplo, se um StreamWriter é armazenado em um estático variável e você não pode facilmente executar código no final da sua vida útil), chamando Flush na StreamWriter após seu último uso ou a configuração do AutoFlush propriedade para true antes de sua primeira utilização deve evitar esse problema.

private static StreamWriter log;
// static class constructor.
static WriteToFile() 
{
    StreamWriter sw = new StreamWriter("log.txt");
    sw.AutoFlush = true;

    // Publish the StreamWriter for other threads.
    log = sw;
}

Efeito sobre o tempo de execução.

Este MDA não tem efeito sobre o tempo de execução.

Saída

Uma mensagem indicando que essa violação ocorreu.

Configuração

<mdaConfig>
  <assistants>
    <streamWriterBufferedDataLost />
  </assistants>
</mdaConfig>

Consulte também

Referência

StreamWriter

Conceitos

Diagnosticar erros com assistentes de depuração gerenciada