Comment puis-je démarrer un fil d'arrière-plan à une heure précise de la journée, par exemple 16h00?
Ainsi, lorsque les applications démarreront, le thread attendra jusqu'à ce moment. Mais si l'application démarre après cette heure, le thread s'exécutera immédiatement
ThreadPool.QueueUserWorkItem(MethodtoRunAt1600);
Vous pouvez configurer une minuterie à 16:00
. J'ai répondu à une question similaire ici . Cela devrait vous aider à coup sûr.
private System.Threading.Timer timer;
private void SetUpTimer(TimeSpan alertTime)
{
DateTime current = DateTime.Now;
TimeSpan timeToGo = alertTime - current.TimeOfDay;
if (timeToGo < TimeSpan.Zero)
{
return;//time already passed
}
this.timer = new System.Threading.Timer(x =>
{
this.SomeMethodRunsAt1600();
}, null, timeToGo, Timeout.InfiniteTimeSpan);
}
private void SomeMethodRunsAt1600()
{
//this runs at 16:00:00
}
Ensuite, configurez-le en utilisant
SetUpTimer(new TimeSpan(16, 00, 00));
Edit: Conservez la référence du Timer car il est sujet à la récupération de place, que le Timer soit actif ou non.
Je voudrais utiliser Job Scheduling Library comme Quartz ou simplement créer une application console et l'exécuter en utilisant le planificateur de tâches Windows à l'heure spécifique de la journée.
Pourquoi ne pas simplement utiliser System.Timers.Timer?
vous pouvez le faire avec une minuterie:
public class OncePerDayTimer : IDisposable
{
private DateTime _lastRunDate;
private TimeSpan _time;
private Timer _timer;
private Action _callback;
public OncePerDayTimer(TimeSpan time, Action callback)
{
_time = time;
_timer = new Timer(CheckTime, null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
_callback = callback;
}
private void CheckTime(object state)
{
if (_lastRunDate == DateTime.Today)
return;
if (DateTime.Now.TimeOfDay < _time)
return;
_lastRunDate = DateTime.Today;
_callback();
}
public void Dispose()
{
if (_timer == null)
return;
_timer.Dispose();
_timer = null;
}
}
Toute solution qui dépend de System.Timers.Timer
, System.Threading.Timer
, ou l'un des autres temporisateurs qui existent actuellement dans le .NET Framework échouera face aux changements d'heure d'été. Si vous utilisez l'un de ces temporisateurs, vous devrez effectuer un sondage.
Windows a un Waitable Timer que vous pouvez utiliser, mais il n'est pris en charge par aucune classe Framework. J'ai écrit un emballage pour cela il y a quelques années. L'article que j'ai publié n'est plus disponible, mais vous pouvez télécharger le code source complet sur http://www.mischel.com/pubs/waitabletimer.Zip
Cela dit, si la seule chose que votre programme fait est exécutée une fois par jour, ou si la tâche qu'il exécute peut être séparée du reste du programme, vous êtes presque certainement mieux avec une tâche planifiée. Et même si je n'ai jamais utilisé Quartz.NET, je n'ai aucun problème à le recommander sur la base des bonnes critiques que j'ai vues de personnes dont je fais confiance.
Voici un moyen simple de planifier une méthode à appeler une fois, immédiatement ou à 16h00.
var runAt = DateTime.Today + TimeSpan.FromHours(16);
if(runAt < DateTime.Now)
{
MethodtoRunAt1600();
}
else
{
var dueTime = runAt - DateTime.Now;
var timer = new System.Threading.Timer(_ => MethodtoRunAt1600(), null, dueTime, TimeSpan.Zero);
}
Si vous cherchez quelque chose de "rapide et sale" ... alors vous pouvez simplement démarrer votre thread dans le pool de threads et "attendre" le bon moment.
// By the way, this code would be *INSIDE* of the background thread. That's what
// the sentence above says, but apparently we devs only read code :)
while (DateTime.Now.TimeOfDay < myDesiredStartTime)
{
Thread.Sleep(1000);
}
Pouvons-nous utiliser comme ça?
DispatcherTimer timer ;
// When application is started
if (DateTime.Now.Hour == 16)
{
// Start your task
}
else
{
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 1, 0);
timer.Tick += timer_Tick;
timer.Start();
}
Ensuite, vérifiez pour chaque minute ..
void timer_Tick(object sender, EventArgs e)
{
if (DateTime.Now.Hour == 16)
{
// Start your task
}
}
Une solution très simple:
if (DateTime.Now.Hour > 16)
{
MethodtoRunAt1600();
}
else
{
var next16 = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 16, 0, 0);
var timer = new Timer(MethodtoRunAt1600, null, next16 - DateTime.Now, TimeSpan.FromHours(24));
timer.Start()
}
C'est quelque chose que j'ai utilisé pour réaliser ce type de fonctionnalité. http://www.codeproject.com/Articles/12117/Simulate-a-Windows-Service-using-ASP-NET-to-run-sc
1- Appelez votre candidature depuis un autre processus
System.Diagnostics.Process.Start("CMD MyApplication.exe", "/C TIME 16:00");
2- Utilisez Timer
et toutes les 1 minute vérifiez l'heure actuelle.
3- Gérez l'événement de changement d'heure de Windows dans votre application et vérifiez à chaque fois l'heure actuelle plus d'informations:
http://msdn.Microsoft.com/en-us/library/Microsoft.win32.systemevents.timechanged%28v=vs.100%29.aspx
J'espère que l'un d'entre eux vous aidera.