Wywołanie metody co x minut


116

Chcę wywoływać jakąś metodę co 5 minut. W jaki sposób mogę to zrobić?

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
lub System.Timers.Timer - dotnetperls.com/timer
sinanakyazici

Odpowiedzi:


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

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

25
Innym sposobem ustawienia interwału jest przekazanie obiektu przedziału czasu. Myślę, że jest trochę czyściej:Timespan.FromMinutes(5)
Michael Haren,

2
@MichaelHaren Nie wiedziałem tego, to jest bardzo miłe. Dziękuję Ci!
asawyer

4
@asawyer Niestety Twoja implementacja powoduje błąd kompilacji. TotalMillisecondszwraca double, podczas gdy licznik czasu oczekuje liczb całkowitych lub TimeSpan. Próbowałem zaktualizować twoją odpowiedź na taką, która zatrudnia TimeSpani wyrzuca niepotrzebne wzdęcia; jednak cofnąłeś to.
André C. Andersen

2
@ AndréChristofferAndersen Zmień 0 w konstruktorze Time na TimeSpan.Zero. Kod działa po tym.
RredCat

2
Kod daje błąd. To jest poprawka new System.Threading.Timer ((e) => {Func ();}, null, TimeSpan.Zero, TimeSpan.FromMinutes (1) .TotalMilliseconds);
Asheh

54

Oparłem to na odpowiedzi @ asawyer. Wydaje się, że nie ma błędu kompilacji, ale niektórzy z nas tak. Oto wersja, którą zaakceptuje kompilator C # w programie Visual Studio 2010.

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

12
Komentowanie dla potomności. Zatrzymałby się, gdy wywołałeś Dispose()metodę w obiekcie timera. Przykład: timer.Dispose()użycie powyższego kodu jako odniesienia. Spowoduje to jednak zniszczenie licznika czasu i uniemożliwi ponowne jego użycie. timer.Change(Timeout.Infinite, Timeout.Infinite)byłoby lepiej, gdybyś chciał ponownie użyć timera w tym samym programie.
Joel Trauger,

1
Ale dlaczego MyMethod () nie działa, gdy uruchamiam ją w aplikacji konsolowej
Izuagbala

@Izuagbala Trudno powiedzieć, dlaczego to nie działa, nie znając szczegółów konfiguracji. To rozwiązanie zostało przetestowane w aplikacji konsolowej.
André C. Andersen

Jaka jest wartość zerowa?
Daniel Reyhanian

@DanielReyhanian Możesz dodać stan obiektu zamiast null, czyli jako argument przy wywołaniu funkcji zwrotnej (tj. Pierwszy argument).
André C. Andersen

7

Uruchom licznik czasu w konstruktorze swojej klasy. Interwał jest wyrażony w milisekundach, więc 5 * 60 sekund = 300 sekund = 300000 milisekund.

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

Następnie zadzwoń GetData()w timer_Elapsedprzypadku takiego zdarzenia:

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

4

Przesłałem pakiet Nuget, który może uczynić to tak prostym, że możesz go mieć tutaj ActionScheduler

Obsługuje .NET Standard 2.0

A oto jak zacząć z niego korzystać

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.

Nie można zainstalować pakietu „CrystalJobScheduler 1.0.0”. Próbujesz zainstalować ten pakiet w projekcie, który jest przeznaczony dla „.NETFramework, Version = v4.5”, ale pakiet nie zawiera żadnych odwołań do zestawów ani plików zawartości, które są zgodne z tą strukturą. Aby uzyskać więcej informacji, skontaktuj się z autorem pakietu.
Aditya Bokade

4

Przykład użycia 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
Zegar lepiej pasuje.
Chuck Conway

1
tak, jeśli cokolwiek, użyj await Task.Delay (60 * 5 * 1000);
CMS
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.