VB .NET - Executando um método periodicamente
Algum dia você pode precisar ter que executar um método de forma periódica em intervalos regulares de tempo. Tarefas como copiar um arquivo, enviar uma mensagem, limpar o cache, etc. Você saberia como fazer isso ?
A classse System.Threading.Timer permite realizar esta tarefa através da execução de um método referenciado pelo delegate TimerCallBack em intervalos pré-definidos. O método referenciado é executado no contexto de uma thread a partir do pool de threads.
A
classe Timer do namespace System.Threading fornece um
mecanismo para executar um método a intervalos
especificados. Você deve usar um delegate TimerCallback para especificar o método que você deseja que o Timer execute. Este delegate é especificado quando o timer é construído, e não pode ser alterado. O método não será executado na thread que criou o timer, mas será executado em uma thread fornecida pelo pool de threads (ThreadPool) fornecido pelo sistema. |
Obs: O delegate TimerCallback representa o método que lida com chamadas de um Timer.
Quando você cria um objeto Timer, define dois intervalos de tempo:
Uma vez criado o objeto Timer , você pode modificar o intervalo usado pelo Timer via método Change, mas não pode alterar o método que foi chamado.
Depois de terminar com o objeto Timer, você deverá chamar o seu método Dispose para liberar os recursos dos sistema. Fazendo isso você cancela qualquer método que estiver agendado para execução.
Vejamos a seguir um exemplo mostrando como usar este recurso:
Vou usar o Visual Basic 2008 Express Edition e criar uma aplicação console que mostra como usar o objeto Timer para chamar o método gerenciaTimer de forma periódica.
Inicialmente o objeto Timer será configurado para chamar o método timerAcionado depois de 5 segundos e então passará a chamá-lo a intervalo de 2 segundos. No exemplo você também pode informar um novo intervalo de tempo via console.
Abra o Visual Basic 2008 Express Edition e crie uma aplicação do tipo Console com o nome de executaMetodoPeriodicamente;
A seguir inclua o seguinte código no modulo:
Imports System Imports System.Threading Namespace Macoratti Class usando_Timer Public Shared Sub Main() ' Cria um objeto estado que é passado para o método timerAcionado ' quando ele é disparado para exibir uma mensagem no console Dim estado As String = "Timer disparado." Console.WriteLine("{0} : Criando o Timer.", DateTime.Now.ToString("HH:mm:ss.ffff")) ' Cria o timer que dispara primeiro depois de 5 segundos e depois a cada 2 segundos ' O objeto threadTimer é liberado automaticcamente no final do bloco using Using threadTimer As New Timer(AddressOf timerAcionado, estado, 5000, 2000) Dim periodo As Integer ' Le um novo intervalo de tempo fornecido a partir do console ' até que o usuário informe 0 (zero). Para valores inválidos será usado ' o valor padrão de zero que irá encerrar o programa Do Try periodo = Int32.Parse(Console.ReadLine()) Catch ex As FormatException periodo = 0 End Try ' Altera o timer para disparar usando o novo intervalo If periodo > 0 Then Console.WriteLine("{0} : Mudando o intervalo do Timer.", DateTime.Now.ToString("HH:mm:ss.ffff")) threadTimer.Change(0, periodo) End If Loop While periodo > 0 End Using ' Aguarda... Console.WriteLine("O método principal foi completado. Pressione Enter.") Console.ReadLine() End Sub Private Shared Sub timerAcionado(ByVal estado As Object) Console.WriteLine("{0} : {1}", DateTime.Now.ToString("HH:mm:ss.ffff"), estado) End Sub End Class End Namespace |
Executando o programa iremos obter:
A classe Timer do namespace System.Threading é um timer mais leve e fácil de usar e que usa os métodos callback e é servido por uma thread do pool de threads.
Usando Timer em aplicações Windows Forms
Não é recomendado a sua utilização em aplicações Windows Forms, pois o callback não ocorre na thread da interface do usuário. Para estas aplicações é recomendado usar System.Windows.Forms.Timer.
No exemplo abaixo, apenas a título de ilustração, vemos como é simples usar a classe Timer do namespace System.Windows.Forms para criar um relógio digital.
Abra o Visual Basic 2008 Express Edition e crie um novo projeto do Aplicativo Windows Forms com o nome relogioDigital.
A seguir inclua o código abaixo no formulário:
Imports System Imports System.Drawing Imports System.Windows.Forms Class DigitalClock Inherits Form Public Shared Sub Main() Application.Run(New DigitalClock()) End Sub Public Sub New() ResizeRedraw = True Dim relogio As New Timer() AddHandler relogio.Tick, AddressOf TimerOnTick relogio.Interval = 1000 relogio.Start() End Sub Private Sub TimerOnTick(ByVal obj As Object, ByVal ea As EventArgs) Invalidate() End Sub Protected Overloads Overrides Sub OnPaint(ByVal pea As PaintEventArgs) Dim grafico As Graphics = pea.Graphics Dim dt As DateTime = DateTime.Now Dim strHora As String = (dt.ToString("d") & vbLf) + dt.ToString("T") Dim tamanhoFonte As SizeF = grafico.MeasureString(strHora, Font) Dim escalaFonte As Single = Math.Min(ClientSize.Width / tamanhoFonte.Width, ClientSize.Height / tamanhoFonte.Height) Dim fonte1 As New Font(Font.FontFamily, escalaFonte * Font.SizeInPoints) Dim strfmt As New StringFormat() strfmt.Alignment = InlineAssignHelper(strfmt.LineAlignment, StringAlignment.Center) grafico.DrawString(strHora, fonte1, New SolidBrush(ForeColor), ClientRectangle, strfmt) End Sub Private Shared Function InlineAssignHelper(Of T)(ByRef destino As T, ByVal valor As T) As T destino = valor Return valor End Function End Class |
Executando o projeto você terá o seu relógio digital:
Eu sei é apenas VB .NET, mas eu gosto...
Referências:
José Carlos Macoratti