Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
amiloM1425

Crash a cancelar thread - System.ObjectDisposedException

Recommended Posts

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;
        }

Share this post


Link to post
Share on other 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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.