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>