Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

amiloM1425

Crash a cancelar thread - System.ObjectDisposedException

Mensagens Recomendadas

amiloM1425

Olá a todos,

Deparei-me com um problema no projecto em que estou envolvido e não estou a conseguir encontrar uma solução.

O problema é o seguinte, em determinada altura da execução da app corro todas as portas COM do computador e envio um comando para cada uma delas à procura de um dispositivo que está ligado a uma delas. Se obtiver a resposta pretendida sei que é ali que se encontra o dispositivo. Até aqui tudo bem e tudo funciona.

O que está a acontecer é que agora que testei a app num computador com bluetooth esta fica bloqueada. Após martelar um pouco verifiquei que o problema vinha da porta COM do bluetooth (COM 3). Verifiquei que isto apenas acontecia quando o dispositivo bluetooth estava "Iniciado", se eu o desligar isto já não acontece, tudo corre normalmente.

Para contornar a questão da app ficar bloqueada comecei a fazer a chamada do método de escrita para a porta COM numa thread à parte com um determinado timeout. Quando ocorre o timeout aborto a execução da thread. O que acontece aqui é que a app fica a funcionar correctamente no entanto aparece a janela do windows a dizer que a alicação deixou de funcionar e se pretendo ou não enviar o relatório para microsoft, claro, se fechar essa janela a app é fechada.

Nos detalhes do relatório vi que o que está a provocar o erro é um System.ObjectDisposeException, pelo que investiguei é por estar a utilizar um  Objecto quando tento fazer o seu dispose, estou correcto? Pelo que me ocorreu que possa ser quando faço o Abort da thread o objecto SerialPort está a ser utilizado.

Já ando aqui às voltas e já não me ocorre nada que possa fazer para contornar esta situação  :wallbash:. Se alguém pudesse dar sugestões agradecia.

Deixo aqui um bocado do código onde tudo isto acontece.

Obrigado.

        SerialPort comPort = null;
        bool encontrado = false;
        string portName = "";
        bool isReading = false;

/// <summary>
/// Envia o pedido de detecção do dispositivo para a porta COM
/// </summary>
private void enviaPedido()
        {
            try
            {
                comPort.Open();
                comPort.Write(pedido, 0, pedido.Length);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// Obtém o nome da porta COM na qual está ligado o dispositivo
        /// </summary>
        /// <returns>Nome da porta COM</returns>
        public string obtemNomePorta()
       {
           comPort = new SerialPort();
           comPort.ReceivedBytesThreshold = 14;
           comPort.ReadBufferSize = 16;
           comPort.BaudRate = 9600;    //BaudRate
           comPort.DataBits = 8;    //DataBits
           comPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), "1");    //StopBits
           comPort.Parity = (Parity)Enum.Parse(typeof(Parity), "0");    //Parity
          
           comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);

            foreach (String portaCom in SerialPort.GetPortNames())
            {
                try
                {
                    if (comPort.IsOpen == false)
                    {
                        comPort.PortName = portaCom;

                        Thread tExecutaPedido= new Thread(new ThreadStart(enviaPedido));
                        tExecutaPedido.Start();
                        tExecutaPedido.Join(2000);

                        if (tExecutaPedido.IsAlive)
                        {
                            try
                            {
                                if (comPort.IsOpen == true && !this.isReading)
                                {
                                    comPort.Close();
                                }
                                tExecutaPedido.Abort();
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                        }

                        //Dá tempo que a resposta seja toda enviada para o buffer da porta COM
                        Thread.Sleep(1000);
                        
                        if (comPort.IsOpen == true && !this.isReading)
                            comPort.Close();

                        if (encontrado)
                        {
                            return portName;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            return null;
        }

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
fLaSh_PT

Tenta criar uma classe que herda o objecto thread.. e adiciona a interface IDisposed.. que fica mais fácil controlares isso..

Compr.


Making the impossible possible and pwing the world on db at a time.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.