Usuário com melhor resposta
Dúvida XmlSerializer

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.
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; }
- Editado Lucas D Santos sexta-feira, 18 de agosto de 2017 14:09
- Marcado como Resposta Mariana C. Costa sexta-feira, 18 de agosto de 2017 18:41
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; }
- Editado Lucas D Santos sexta-feira, 18 de agosto de 2017 14:09
- Marcado como Resposta Mariana C. Costa sexta-feira, 18 de agosto de 2017 18:41
-
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();
-
-
-
-