none
Como fazer um Timer em um projeto Class Library

    Question

  • Olá amigos,

    Preciso fazer um Timer em meu componente. Alguém pode me ensinar como fazer ?

    Obrigado
    Wednesday, December 09, 2009 1:37 PM

Answers

All replies

  • Eduardo,

    Existe uma classe Timer no .NET. Pode ser mais específico?

    Timer Class
    http://msdn.microsoft.com/en-us/library/system.threading.timer.aspx

    Att.

    Ari C. Raimundo
    Wednesday, December 09, 2009 1:45 PM
    Moderator
  • É o seguinte,

    Meu objetivo é monitorar uma conexão socket que receberá dados na maior parte das vezes, porém, pode ocorrer de o servidor parar um tempo de enviar dados por algum motivo ou por nao ter dados a serem enviados.. Preciso colocar um tempo para essa verificação.. Se parar de receber dados, inicia a contagem de tempo (no caso 5 min) e se estourar o tempo eu exibo uma mensagem de timeout.

    Ficou claro ?

    Obrigado

    Wednesday, December 09, 2009 1:53 PM
  • Veja o código abaixo:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Timers;
    
    namespace TestTimer {
        class Program {
            static void Main(string[] args) {
                //declaração do timer e do tempo
                // 2000 como tempo significam 2 segundos
                // 300000 (trezentos mil) como tempo significam 5 minutos
                Timer t = new System.Timers.Timer(2000);
                t.Elapsed += new ElapsedEventHandler(t_Elapsed);
    
                //em algum ponto vc irá iniciar o timer, ou seja,
                //quando parar de receber dados você inicia
                t.Start();
    
                //se em algum ponto você precisa parar o timer, como 
                //no caso de ter iniciado mas antes dos 5 minutos você recebeu
                //dados, então você para o timer
                
                t.Stop();
            }
    
            static void t_Elapsed(object sender, ElapsedEventArgs e) {
                Console.WriteLine("TimeOut em " + e.SignalTime.ToString());            
            }
        }
    }
    Ok, foi um código simples, creio que você já saberia fazer antes mesmo dessa resposta, agora o interessante é que quando temos algum trabalho com Threads, ou usando os BackgroundWorkers, nós temos que eventualmente iniciar ou parar nossos Timers, mudando alguma propriedade dele, para isso, você pode usar um código semelhante ao abaixo, que eu uso num windows service que abre threads que usam timers para controlar algumas coisas, veja a seguir:

            private void SetControlPropertyValue(System.Timers.Timer oControl, string propName, object propValue)
            {
                Type t = oControl.GetType();
                PropertyInfo[] props = t.GetProperties();
                foreach (PropertyInfo p in props)
                {
                    if (p.Name.ToUpper() == propName.ToUpper())
                    {
                        p.SetValue(oControl, propValue, null);
                    }
                }
            }
    Então, dentro de sua thread/método onde você está recebendo os dados do servidor, você pode usar o seguinte código quando quiser parar ou iniciar o timer:

    //para habilitar o timer
    SetControlPropertyValue(t, "enabled", true);
    
    //para parar o timer
    SetControlPropertyValue(t, "enabled", false);
    
    Espero ter ajudado.

    Att.
    • Proposed as answer by Thiago R. Costa Wednesday, December 09, 2009 3:46 PM
    Wednesday, December 09, 2009 3:42 PM
  • Boa tarde Thiago, não consigo referenciar o System.Linq;

    Estou fazendo um Class Library.

    Valeu !
    Wednesday, December 09, 2009 4:46 PM
  • Eduardo,

    Eu passei o link errado da classe Timer, o Thiago apontou a classe correta. O link correto é esse:

    Timer Class
    http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx

    Em relação a sua dúvida sobre a referência da classe System.Linq, não foi utilizado nenhuma consulta em LINQ no código, pode apagar essa linha.

    Att.

    Ari C. Raimundo
    • Marked as answer by Eduardo Gório Thursday, December 10, 2009 10:48 AM
    Wednesday, December 09, 2009 5:56 PM
    Moderator
  • Thiago,

    Posso estar enganado, mas pelo que percebi o seu método SetControlPropertyValue não é thread-safe. Você somente define a propriedade por meio de Reflection, mas isso não garante que seja thread-safe. É o mesmo que utilizar a propriedade diretamente.

    Estou enganado?

    Att.

    Ari C. Raimundo
    Wednesday, December 09, 2009 6:03 PM
    Moderator
  •            // Dados recebidos pelo socket
                public void OnRecieveData(IAsyncResult ar)
                {
                    Socket sock = (Socket)ar.AsyncState;
                    try
                    {
                        int nBytesRec = sock.EndReceive(ar);
                        if (nBytesRec > 0)
                        {
                            msg += Encoding.UTF8.GetString(buffer, 0, nBytesRec);
                            if (nBytesRec == 2048)
                            {
                                WaitForData(sock);
                            }
                            else
                            {
                                CPR_datareceived = msg.Substring(0, msg.Length - 1);
    
                                if (CPR_Key == string.Empty)
                                {
                                    try
                                    {
                                        Match m = Regex.Match(msg, "{.*}");
                                        if (m.Length > 0)
                                        {
                                            CPR_Key = m.Value.Trim().Substring(m.Value.Trim().IndexOf("{") + 1, m.Value.Trim().IndexOf("}") - m.Value.Trim().IndexOf("{") - 1);
                                        }
                                    }
                                    catch (Exception)
                                    {
                                    }
                                }
                                msg = "";
                                //Dispara o evento OnDataReceived
                                OnDataReceived(ar);
    
                                Regex exp = new Regex("Disconnect");
                                if (exp.IsMatch(CPR_datareceived))
                                {
                                    Disconnect();
                                    TimeOut_time = 0;
                                }
                                else if (lido)
                                {
                                    lido = false;
                                }
                                else
                                {
                                    TimeOut_time++;
                                }
                            }
                        }
                        else
                        {
                            sock.Shutdown(SocketShutdown.Both);
                            sock.Close();
                        }
                    }
                    catch (ArgumentException se)
                    {
                        if (OnError != null)
                            OnError(ErrorLog(Convert.ToString(se.Message), 31), null, 31);
                    }
                    catch (InvalidOperationException se)
                    {
                        sock.Close();
                        if (!sock.Connected)
                            if (OnDisconnect != null)
                                OnDisconnect(sock);
                        if (OnError != null)
                            OnError(ErrorLog(Convert.ToString(se.Message), 32), null, 32);
                    }
                    catch (SocketException se)
                    {
                        if (OnError != null)
                            OnError(ErrorLog(Convert.ToString(se.Message), 33), sock, 33);
                        if (!sock.Connected)
                            if (OnDisconnect != null)
                                OnDisconnect(sock);
                    }
                    catch (Exception)
                    {
                    }
                    if (CPR_timeout < 5)
                        WaitForData(sock);
                    else
                        TimeOut_Verify(CPR_timeout);
                }
    
                static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
                static bool exitFlag = false;
                
                public void TimeOut_Verify(int time)
                {
                    myTimer.Tick += new EventHandler(TimerEventProcessor);
    
                    // Sets the timer interval to 5 seconds.
                    myTimer.Interval = 5000;
                    myTimer.Start();
    
                    // Runs the timer, and raises the event.
                    while (exitFlag == false)
                    {
                        // Processes all the events in the queue.
                        Application.DoEvents();
                    }
                    MessageBox.Show("TIMER");
                }
    
                // This is the method to run when the timer is raised.
                private static void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
                {
                    myTimer.Stop();
                    myTimer.Enabled = false;
                    // Stops the timer.
                    exitFlag = true;
                }
    
                // Verifica se há dados vindo do socket
                public void WaitForData(Socket sock)
                {
                    try
                    {
                        AsyncCallback recieveData = new AsyncCallback(OnRecieveData);
                        sock.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, recieveData, sock);
                        //Se chegou aqui é pq há dados
                        if (OnRead != null)
                            OnRead(sock);
                    }
                    catch (SocketException se)
                    {
                        if (OnError != null)
                            OnError(ErrorLog(Convert.ToString(se.Message), 40), sock, 40);
                    }
                    catch (Exception)
                    {
                    }
                }
    Até funciona o Timer agora, só que quando clico em OK ele trava o programa..

    Colei a parte que interessa do código acima.

    Obrigado Ari.. ta quase 100%

    Funcionando o Timer, vou alterar a lógica de acordo com o que eu preciso..
    Wednesday, December 09, 2009 6:40 PM
  • Você pode remover a referência a System.Linq que o código vai funcionar normalmente, até porque a intenção era mostrar a classe do timer sendo instanciada, iniciada, e a possibilidade de iniciar e parar ela de dentro de threads.

    Att.

    Thursday, December 10, 2009 11:30 AM
  • Ari C. Raimundo,

    Uso dessa forma em um Windows Service e funciona perfeitamente. Tenho o timer instanciado em um método que não está na thread, e quando a thread é iniciada, em determinado momento eu preciso parar o timer e depois iniciá-lo novamente de dentro do método executado pela thread, então eu faço da maneira como coloquei.

    =)

    Att.

    Thursday, December 10, 2009 11:33 AM