none
Trabalhando com threads RRS feed

  • Pergunta

  • "O thread atual deve ser definido no modo STA (single thread apartment) antes que chamadas OLE possam ser feitas. Verifique se a função Main tem STAThreadAttribute marcado. A exceção somente será gerada se um depurador estiver anexado ao processo."

    Esse foi o erro gerado quando eu tentei realizar o comando DialogResult result = sf.ShowDialog(); dentro de um método que uma thread está consumindo.

    Acredito ser conceito bem besta, porém estou esquecendo. Alguem pode ajudar?

    segunda-feira, 30 de julho de 2012 12:43

Respostas

  • Antes de iniciar sua Thread você tem que colocar 

    sua_thread.ApartmentState = ApartmentState.STA; 


    e antes de seu Main, coloque essa anotação

    [STAThread]

    Tente também chamar via Invoke

    Invoke((Action)(() => { saveFileDialog.ShowDialog() }));


    Se a sugestão resolver o problema, favor marcar como Resposta.


    • Editado Lucas_Santos segunda-feira, 30 de julho de 2012 12:49
    • Marcado como Resposta LucasSchoch segunda-feira, 30 de julho de 2012 12:54
    segunda-feira, 30 de julho de 2012 12:48

Todas as Respostas

  • Antes de iniciar sua Thread você tem que colocar 

    sua_thread.ApartmentState = ApartmentState.STA; 


    e antes de seu Main, coloque essa anotação

    [STAThread]

    Tente também chamar via Invoke

    Invoke((Action)(() => { saveFileDialog.ShowDialog() }));


    Se a sugestão resolver o problema, favor marcar como Resposta.


    • Editado Lucas_Santos segunda-feira, 30 de julho de 2012 12:49
    • Marcado como Resposta LucasSchoch segunda-feira, 30 de julho de 2012 12:54
    segunda-feira, 30 de julho de 2012 12:48
  • using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Oracle.DataAccess.Client;
    using System.Windows.Forms;
    using System.IO;
    using System.Data;
    using System.ComponentModel;
    using System.Threading;
    namespace Sistema
    {
        class Contabilizacao
        {
            public void GerarRelatorioContab()
            {
                Thread td = new Thread(new ThreadStart(this.Principal));
                td.IsBackground = true;
                td.Start();
            }
            [STAThread]
            private void RelatorioContabilizar(int mes, int ano)
            {
                string caption = "Tem certeza que deseja gerar para todas as filiais o arquivo de contabilização referente a data " + mes + "/" + ano + "?";
                DialogResult rs = MessageBox.Show(caption, "Validação", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (rs == DialogResult.OK)
                {
                    SaveFileDialog sf = new SaveFileDialog();
                    sf.InitialDirectory = "C:\\";
                    sf.FileName = "Contabilizacao";
                    sf.Filter = "Txt files (*.txt)|*.txt";
                    DialogResult result = sf.ShowDialog();
                    if (result == System.Windows.Forms.DialogResult.OK)
                    {
                        MessageBox.Show("Continue utilizando o sistema." + Environment.NewLine
                                  + "Ao término da tarefa, uma mensagem de confirmação será exibida.", "Informativo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        try
                        {
                            OracleConnection conn = Conexoes.ConexaoINTRHLOG();
                            OracleCommand cmd = new OracleCommand();
                            cmd.Connection = conn;
                            cmd.CommandText = "";
                            OracleDataAdapter da = new OracleDataAdapter();
                            da.SelectCommand = cmd;
                            DataTable dtContab = new DataTable();
                            dtContab.Clear();
                            da.Fill(dtContab);
                            if (dtContab.Rows.Count > 0)
                            {
                                string path = sf.FileName;
                                StreamWriter sw = new StreamWriter(@path);
                                for (int i = 0; i < dtContab.Rows.Count; i++)
                                {
                                    string varA = Convert.ToString(dtContab.Rows[i]["DADOS"]);
                                    sw.WriteLine(varA);
                                }
                                sw.Flush();
                                MessageBox.Show("Contabilização gerada com sucesso!", "Sucesso",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            else
                            {
                                throw new Exception();
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("Erro ao gerar Contabilização." + Environment.NewLine
                            + "Não foi possível acessar os dados para executar a tarefa." + ex.Message, "Erro",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                        }
                    }
                    else
                    {
                        MessageBox.Show("A Contabilização foi cancelada. ", "Contabilização Cancelada",
                            MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    }
                }
                else
                {
                    MessageBox.Show("A Contabilização foi cancelada.", "Contabilização Cancelada",
                        MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
            [STAThread]
            public void Principal()
            {
                DateTime today = DateTime.Now;
                int todayDay = Convert.ToInt32(today.ToString().Substring(0, 2));
                int todayMes = Convert.ToInt32(today.ToString().Substring(3, 2));
                int todayAno = Convert.ToInt32(today.ToString().Substring(6, 4));
                //int mes = Convert.ToInt32(maskPeriodo.Text.Substring(0, 2));
                //int ano = Convert.ToInt32(maskPeriodo.Text.Substring(3, 4));
                ContadorDeDias cdd = new ContadorDeDias();
                int retorno = cdd.RetornaTerceiroDiaUtil(todayMes, todayAno);
                if (retorno < todayDay)
                {
                    if (todayMes == 1)
                    {
                        RelatorioContabilizar(12, todayAno - 1);
                    }
                    RelatorioContabilizar(todayMes - 1, todayAno);
                }
                else
                {
                    MessageBox.Show("Não foi possível gerar a Contabilização devido a possível defasagem de 3(três) dias." + Environment.NewLine
                        + "Aguarde até o terceiro dia útil do mês atual para gerar a contabilização do mâs anterior.", "Contabilização Cancelado",
                           MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
        }
    }

    segunda-feira, 30 de julho de 2012 12:49
  • Não entendi o ''Invoke'' porém funcionou por alterar o ApartmentState.

    Obrigado.

    segunda-feira, 30 de julho de 2012 12:54
  • ShowDialog() não pode ser chamado de uma thread em background.

    Se a sugestão resolver o problema, favor marcar como Resposta.

    segunda-feira, 30 de julho de 2012 12:58
  • Funcionando, a microsoft aparentemente descontinuou o thread.ApartmentState = ApartmentState.STA;
    Utilize o thread.SetApartmentState(ApartmentState.STA);
    segunda-feira, 30 de julho de 2012 13:01