Chamando um método a cada x minutos


116

Quero chamar algum método a cada 5 minutos. Como posso fazer isso?

public class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("*** calling MyMethod *** ");
        Console.ReadLine();
    }

    private MyMethod()
    {
        Console.WriteLine("*** Method is executed at {0} ***", DateTime.Now);
        Console.ReadLine();
    }
}

10
System.Threading.Timer
user703016

1
ou System.Timers.Timer - dotnetperls.com/timer
sinanakyazici

Respostas:


182
var startTimeSpan = TimeSpan.Zero;
var periodTimeSpan = TimeSpan.FromMinutes(5);

var timer = new System.Threading.Timer((e) =>
{
    MyMethod();   
}, null, startTimeSpan, periodTimeSpan);

25
Outra maneira de definir o intervalo é passando um objeto de intervalo de tempo. Eu acho que é um pouco mais limpo:Timespan.FromMinutes(5)
Michael Haren

2
@MichaelHaren Eu não sabia disso, isso é muito bom. Obrigado!
advogado de

4
@asawyer Infelizmente, sua implementação apresenta um erro de compilação. TotalMillisecondsretorna um duplo enquanto o cronômetro espera números inteiros ou TimeSpan. Tentei atualizar sua resposta para uma que emprega TimeSpane elimina inchaços desnecessários; no entanto, você o reverteu.
André C. Andersen

2
@ AndréChristofferAndersen Altere 0 no construtor Time para TimeSpan.Zero. O código funciona depois disso.
RredCat 01 de

2
O código dá um erro. Esta é a correção new System.Threading.Timer ((e) => {Func ();}, null, TimeSpan.Zero, TimeSpan.FromMinutes (1) .TotalMilliseconds);
Asheh

54

Eu baseei isso na resposta de @asawyer. Ele não parece obter um erro de compilação, mas alguns de nós sim. Aqui está uma versão que o compilador C # no Visual Studio 2010 aceitará.

var timer = new System.Threading.Timer(
    e => MyMethod(),  
    null, 
    TimeSpan.Zero, 
    TimeSpan.FromMinutes(5));

12
Comentando para a posteridade. Ele pararia quando você chamasse o Dispose()método no objeto timer. Exemplo: timer.Dispose()usando o código acima como referência. No entanto, isso destruirá o cronômetro e impedirá que você o use novamente. timer.Change(Timeout.Infinite, Timeout.Infinite)seria melhor se você quiser usar o cronômetro novamente no mesmo programa.
Joel Trauger,

1
Mas por que MyMethod () não é executado quando eu o executo no aplicativo de console
Izuagbala

@Izuagbala É difícil dizer por que não funciona para você sem saber os detalhes de como você o configurou. Esta solução foi testada em um aplicativo de console.
André C. Andersen

Qual é o nulo?
Daniel Reyhanian

@DanielReyhanian Você pode adicionar um estado de objeto em vez de null, ou seja, como um argumento ao chamar a função de retorno de chamada (ou seja, o primeiro argumento).
André C. Andersen

7

Inicie um cronômetro no construtor de sua classe. O intervalo é em milissegundos, portanto 5 * 60 segundos = 300 segundos = 300000 milissegundos.

static void Main(string[] args)
{
    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Interval = 300000;
    timer.Elapsed += timer_Elapsed;
    timer.Start();
}

Em seguida, chame GetData()o timer_Elapsedevento desta forma:

static void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    //YourCode
}

4

Fiz upload de um pacote Nuget que pode torná-lo tão simples, você pode obtê-lo aqui. ActionScheduler

Suporta .NET Standard 2.0

E aqui como começar a usá-lo

using ActionScheduler;

var jobScheduler = new JobScheduler(TimeSpan.FromMinutes(8), new Action(() => {
  //What you want to execute
}));

jobScheduler.Start(); // To Start up the Scheduler

jobScheduler.Stop(); // To Stop Scheduler from Running.

Não foi possível instalar o pacote 'CrystalJobScheduler 1.0.0'. Você está tentando instalar este pacote em um projeto que tem como objetivo '.NETFramework, Version = v4.5', mas o pacote não contém nenhuma referência de montagem ou arquivos de conteúdo compatíveis com essa estrutura. Para obter mais informações, entre em contato com o autor do pacote.
Aditya Bokade

4

Exemplo de uso de Timer:

using System;
using System.Timers;

static void Main(string[] args)
{
    Timer t = new Timer(TimeSpan.FromMinutes(5).TotalMilliseconds); // Set the time (5 mins in this case)
    t.AutoReset = true;
    t.Elapsed += new System.Timers.ElapsedEventHandler(your_method);
    t.Start();
}

// This method is called every 5 mins
private static void your_method(object sender, ElapsedEventArgs e)
{
    Console.WriteLine("..."); 
}


0
while (true)
{
    Thread.Sleep(60 * 5 * 1000);
    Console.WriteLine("*** calling MyMethod *** ");
    MyMethod();
}

10
Um cronômetro é um ajuste melhor.
Chuck Conway,

1
sim, se houver alguma coisa, use await Task.Delay (60 * 5 * 1000);
CMS de
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.