none
Dúvida XmlSerializer RRS feed

  • Pergunta

  • Estou serializando uma NF-e, e funciona perfeita, porém eu preciso, deixar o arquivo livre, sem ficar utilizando, pois está barrando, segue o código:

    StringWriter sw = new StringWriter();
                XmlTextWriter tw = new XmlTextWriter(sw);
    
                XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
                xsn.Add("", "http://www.portalfiscal.inf.br/nfe");
    
     XmlSerializer ser = new XmlSerializer(typeof(TNFe));
                    FileStream arquivo = new FileStream("C:\\" + chave_nfe + "-NFe.xml", FileMode.CreateNew);
    
                    ser.Serialize(arquivo, nfe, xsn);

    Se eu faço:

    sw.Close();

    O arquivo ainda continua em uso, e não funciona como esperado. E se eu faço:

    arquivo.Dispose();

    Funciona, só que ele não monitora a pasta, não entendo o porque disso ocorrer, o código de monitoramento é logo em seguida:

    form = new FormProgressBar();
                    form.Show();
    
                int X = 6000;
                form.MaximumBar(X);
    
                // Faço o laço para atualizar a barra
                for (int i = 0; i < X; i++)
                {
                    // Método que atualiza a barra e o texto da barra
                    form.AtualizaBarra("Aguarde...");
                    // Insiro algum código que desejo e vou mostrando o status da atualização
                }
                // clsdb.ExecutaSQL("insert into nfe (n_nota, chave) values ('" + txtnumero.Text + "','" + digito(chave) + "')");
                messagebox = 0;
                messageboxxml = 0;
                #region MONITORAR PASTA
    
    
    
                //Dizemos agora se é para monitorar os subdiretórios ou não
                fsw.IncludeSubdirectories = false;
    
                //Através de um Enum dizemos quais eventos devem ser monitorados, modificação da data do arquivo, tamanho, etc...
                fsw.NotifyFilter = NotifyFilters.FileName | NotifyFilters.LastWrite;
    
                //Dizemos quais tipos de arquivos devem ser monitorados, *.*, *.xml, *.txt, etc...
                //fsw.Filter = "*.xml";
                //fsw.Filter = "*.ERR";
    
                //Definimos agora os eventos a serem gerados
                fsw.Created += new FileSystemEventHandler(fsw_Created);
                fsw.Changed += new FileSystemEventHandler(fsw_Changed);
                fsw.Error += new ErrorEventHandler(fsw_Error);
    
                //A propriedade abaixo define que a monitoração deve iniciar, se false, a pasta não será monitorada
                fsw.EnableRaisingEvents = true;

    Como posso fazer, para que o arquivo fique livre para ser tratado, e que o monitoramento continue funcionando? Obrigado.



    sexta-feira, 18 de agosto de 2017 12:13

Respostas

  • Marina bom dia tente chamar o método flush dos writers e uma dica é usar o using() nas instancias das classes que implementam IDispose pois isto garante que ao sair do using(){} o .net irá realizar a execução di .Dispose() da classe, tente algo como:

                                        using (StreamWriter sw = new StreamWriter("C:\\" + chave_nfe + "-NFe.xml"))
                                        {
                                            using (XmlTextWriter tw = new XmlTextWriter(sw))
                                            {
                                                XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
                                                xsn.Add("", "http://www.portalfiscal.inf.br/nfe");
    
                                                XmlSerializer ser = new XmlSerializer(typeof(TNFe));
                                                ser.Serialize(sw, nfe, xsn);
    
                                                tw.Flush();
                                                tw.Close();
                                            }
                                            sw.Flush();
                                            sw.Close();
                                        }

    Uma outra coisa é que o watcher irá pegar o arquivo sempre que ele for criado e ainda estiver em uso pelo sistema, assim uma coisa que pode fazer é criar um método para testar se o arquivo ainda tem bloqueio e verificar se o arquivo solicitado já está liberado, um método mais ou menos assim:

    private bool IsFileBlocked(string path)
    {
        FileStream stream = null;
    
        try
        {
            stream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
        }
        catch (IOException)
        {
            return true;
        }
        finally
        {
            if (stream != null)
                stream.Close();
        }
    
        return false;
    }


    sexta-feira, 18 de agosto de 2017 14:04

Todas as Respostas

  • Marina bom dia tente chamar o método flush dos writers e uma dica é usar o using() nas instancias das classes que implementam IDispose pois isto garante que ao sair do using(){} o .net irá realizar a execução di .Dispose() da classe, tente algo como:

                                        using (StreamWriter sw = new StreamWriter("C:\\" + chave_nfe + "-NFe.xml"))
                                        {
                                            using (XmlTextWriter tw = new XmlTextWriter(sw))
                                            {
                                                XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
                                                xsn.Add("", "http://www.portalfiscal.inf.br/nfe");
    
                                                XmlSerializer ser = new XmlSerializer(typeof(TNFe));
                                                ser.Serialize(sw, nfe, xsn);
    
                                                tw.Flush();
                                                tw.Close();
                                            }
                                            sw.Flush();
                                            sw.Close();
                                        }

    Uma outra coisa é que o watcher irá pegar o arquivo sempre que ele for criado e ainda estiver em uso pelo sistema, assim uma coisa que pode fazer é criar um método para testar se o arquivo ainda tem bloqueio e verificar se o arquivo solicitado já está liberado, um método mais ou menos assim:

    private bool IsFileBlocked(string path)
    {
        FileStream stream = null;
    
        try
        {
            stream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
        }
        catch (IOException)
        {
            return true;
        }
        finally
        {
            if (stream != null)
                stream.Close();
        }
    
        return false;
    }


    sexta-feira, 18 de agosto de 2017 14:04
  • Boa Tarde Lucas, usei o using e funcionou, deu certo, mas depois que mudei, sabe o que o ocorre, o form não fecha, eu coloco este código no button close:

     try
                {
                    fsw.EnableRaisingEvents = false;
                    fsw.Dispose();
                    Close();
                }
                catch
                {
                    this.Close();
                }

    Não consigo entender o pq, se eu comento o código de monitoramento funciona, caso ele monitora, ele não fecha, mesmo eu fazendo o Dispose();

    sexta-feira, 18 de agosto de 2017 15:54
  • Mariana se roda a aplicação debugando estoura alguma exceção ao clicar no botão de fechar?
    sexta-feira, 18 de agosto de 2017 17:29
  • Não, ele simplesmente não fecha, mas se eu comento a parte de monitoramento, ele fecha normal, só depois de acionar o monitoramento que ele não fecha. Não entendi pq, antes ele fechava normal.
    sexta-feira, 18 de agosto de 2017 17:32
  • Realmente é estranho consegue notar se no Output panel aparece alguma informação quando você clica no botão de fechar? Dente debugar o método do botão e note se em alguma das linhas aparece alguma entrada diferente no output panel.
    sexta-feira, 18 de agosto de 2017 18:25
  • Descobri aonde estava o problema, na verdade estava no progressbar e não no monitorar, estou tentado resolver. Obrigado.
    sexta-feira, 18 de agosto de 2017 18:41