none
Método em thread separada ainda travando interface. RRS feed

  • Pergunta

  • Estou querendo colocar um método que busca e altera arquivos do word em uma thread separada. Cheguei ai código abaixo, mas é como se não tivesse feito nada. O código executa e a aplicação permanece travada. Alguém pode dizer onde estou errando? Grato.

      private void btn_Selecionar_Click_1(object sender, EventArgs e)
            {
    
                Thread t1 = new Thread(new ThreadStart(MetodoWord));
                t1.Start();
    
    
    
    
            } //Fim Botão
    
    
    
            //Método WORD (Find and Replace)
    
             public void MetodoWord()
            {
    
    
                if (this.InvokeRequired)
    
                {
                    this.Invoke(new MethodInvoker(MetodoWord));
                    return;
                }
    
    
    
                Microsoft.Office.Interop.Word.Application ap = new Microsoft.Office.Interop.Word.Application();
                var fbd = new FolderBrowserDialog();
                fbd.Description = "Selecione a pasta que possue os arquivos a serem pesquisados:";
                DialogResult result = fbd.ShowDialog();
    
                if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
                {
    
    
    
    
                    int changes = 0;
    
                    var files = Directory.GetFiles(fbd.SelectedPath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".doc") || s.EndsWith(".docx"));
                    int filecountdoc = Directory.GetFiles(fbd.SelectedPath, "*.doc", SearchOption.AllDirectories).Length;
                    progressBar1.Maximum = filecountdoc;
                    progressBar1.Minimum = 0;
    
                    try
                    {
    
    
                        foreach (string s in files)
                        {
                            Document doc = ap.Documents.Open(s);
                            doc.Activate();
                            Microsoft.Office.Interop.Word.Find fnd = ap.ActiveWindow.Selection.Find;
                            fnd.ClearFormatting();
                            fnd.Replacement.ClearFormatting();
                            fnd.Forward = true;
                            fnd.MatchCase = true;
                            fnd.Wrap = Microsoft.Office.Interop.Word.WdFindWrap.wdFindContinue;
                            fnd.Text = txt_Localizar.Text;
                            fnd.Replacement.Text = txt_Substituir.Text;
                            fnd.Execute(Replace: WdReplace.wdReplaceAll);
    
                            if (fnd.Found == true)
                                changes += 1;
    
    
                            //Cabeçalho e Rodapé
                            foreach (Microsoft.Office.Interop.Word.Section section in doc.Sections)
                            {
                                Microsoft.Office.Interop.Word.Range footerRange = section.Footers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary].Range;
                                footerRange.Find.Text = txt_Localizar.Text;
                                footerRange.Find.Replacement.Text = txt_Substituir.Text;
                                footerRange.Find.Execute(Replace: WdReplace.wdReplaceAll);
    
                                if (footerRange.Find.Found == true)
                                    changes += 1;
    
    
                            }
    
                            doc.Save();
                            doc.Close();
                            progressBar1.Increment(1);
    
    
                        }
    
                    }
                    catch (Exception)
                    {
    
                        throw;
                    }
    
                    finally
                    {
    
                        txt_Localizar.Clear();
                        txt_Substituir.Clear();
                        MessageBox.Show(changes + " arquivo(s) alterado(s)");
                        progressBar1.Value = 0;
                    }
    
    
                }
    
    
    
            }

    terça-feira, 13 de março de 2018 11:39

Respostas

  • Acredito que seu erro é a linha abaixo:

    this.Invoke(new MethodInvoker(MetodoWord));

    Ela deve ser utilizada quando uma BackgroundThread precisa acessar elementos da interface (UI), porém você colocou toda sua lógica no MetodoWord, então acredito que possa ser o seu problema.

    Talvez se você usar o Invoke apenas para as partes que realmente devem interagir com a interface, já funcione.

    PS: Estou falando talvez, pois no ambiente que estou não tenho Visual Studio para testar.


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.

    terça-feira, 13 de março de 2018 12:00

Todas as Respostas

  • Acredito que seu erro é a linha abaixo:

    this.Invoke(new MethodInvoker(MetodoWord));

    Ela deve ser utilizada quando uma BackgroundThread precisa acessar elementos da interface (UI), porém você colocou toda sua lógica no MetodoWord, então acredito que possa ser o seu problema.

    Talvez se você usar o Invoke apenas para as partes que realmente devem interagir com a interface, já funcione.

    PS: Estou falando talvez, pois no ambiente que estou não tenho Visual Studio para testar.


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.

    terça-feira, 13 de março de 2018 12:00
  • Acredito que seu erro é a linha abaixo:

    this.Invoke(new MethodInvoker(MetodoWord));

    Ela deve ser utilizada quando uma BackgroundThread precisa acessar elementos da interface (UI), porém você colocou toda sua lógica no MetodoWord, então acredito que possa ser o seu problema.

    Talvez se você usar o Invoke apenas para as partes que realmente devem interagir com a interface, já funcione.

    PS: Estou falando talvez, pois no ambiente que estou não tenho Visual Studio para testar.


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.

    Exatamente isso!!! Muito obrigado. Queria saber 10% do que vocês sabem.
    terça-feira, 13 de março de 2018 13:43
  • Excelente meu caro.

    Lembre-se de marcar a resposta como aceita e como útil. ;-)


    Juliano Nunes - http://linkedin.com/in/julianonunes

    Lembre-se de clicar em "Votar como útil" e "Marcar como Resposta" caso tenha respondido sua dúvida.

    Remember to "Vote as Helpful" and "Mark as Answer" if your question has been answered.

    terça-feira, 13 de março de 2018 13:47