C#:如何在特定时间启动线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18611226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C#: How to start a thread at a specific time
提问by Bob
How can I start a background thread at a specific time of day, say 16:00?
如何在一天中的特定时间启动后台线程,比如 16:00?
So when the apps starts up the thread will wait until that time. But if the app starts up after that time then the thread will run straight away
因此,当应用程序启动时,线程将等到那个时候。但是如果应用程序在那之后启动,那么线程将立即运行
ThreadPool.QueueUserWorkItem(MethodtoRunAt1600);
ThreadPool.QueueUserWorkItem(MethodtoRunAt1600);
采纳答案by Sriram Sakthivel
You can set up a timer at 16:00
. I've answered a similar question here.
That should help you for sure.
您可以在 上设置计时器16:00
。我在这里回答了一个类似的问题。那肯定对你有帮助。
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
}
Then set it up using
然后使用它进行设置
SetUpTimer(new TimeSpan(16, 00, 00));
Edit: Keep the reference of the Timer as it's subject to garbage collection irrespective of the Timer is active or not.
编辑:保留 Timer 的引用,因为无论 Timer 是否处于活动状态,它都会受到垃圾收集的影响。
回答by Damith
I would use Job Scheduling Library like Quartzor simply create console application and run it using windows task scheduler at the specific time of the day.
我会使用像Quartz这样的作业调度库,或者只是创建控制台应用程序并在一天中的特定时间使用 Windows 任务调度程序运行它。
Why not just use System.Timers.Timer?
- Timers have no persistence mechanism.
- Timers have inflexible scheduling (only able to set start-time & repeat interval, nothing based on dates, time of day, etc.
- Timers don't utilize a thread-pool (one thread per timer)
- Timers have no real management schemes - you'd have to write your own mechanism for being able to remember, organize and retreive your tasks by name, e
- 定时器没有持久化机制。
- 计时器具有不灵活的调度(只能设置开始时间和重复间隔,不能根据日期、时间等设置)。
- 计时器不使用线程池(每个计时器一个线程)
- 计时器没有真正的管理方案——您必须编写自己的机制,以便能够通过名称来记住、组织和检索您的任务,例如
回答by Timothy Khouri
If you're looking for something "quick and dirty"... then you could just start your thread in the thread pool, and "wait" for the right time.
如果您正在寻找“快速而肮脏”的东西……那么您可以在线程池中启动您的线程,然后“等待”合适的时间。
// 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);
}
回答by Naren
Can we use like this?
我们可以这样使用吗?
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();
}
Then check for every one minute..
然后每隔一分钟检查一次..
void timer_Tick(object sender, EventArgs e)
{
if (DateTime.Now.Hour == 16)
{
// Start your task
}
}
回答by Jordy Langen
A very simple solution:
一个非常简单的解决方案:
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()
}
回答by Bassam Alugili
1- Call your application from another process
1- 从另一个进程调用您的应用程序
System.Diagnostics.Process.Start("CMD MyApplication.exe", "/C TIME 16:00");
2- Use Timer
and each 1 minute check the current time.
2- 使用Timer
并每 1 分钟检查一次当前时间。
3- Handle the Windows time changed event in your appliction and each time also check the current time more info:
3- 在您的应用程序中处理 Windows 时间更改事件,并且每次还检查当前时间更多信息:
http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.timechanged%28v=vs.100%29.aspx
http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.timechanged%28v=vs.100%29.aspx
I hope one of thoese will help you.
我希望其中之一会帮助你。
回答by jgauffin
you can do it with a timer:
你可以用计时器来做到这一点:
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;
}
}
回答by Steve Ruble
Here's a simple way to schedule a method to be called once, either immediately or at 16:00.
这是安排一个方法调用一次的简单方法,可以立即调用,也可以在 16:00 调用。
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);
}
回答by Ali Umair
This is something i used for achieving this kind of functionality. http://www.codeproject.com/Articles/12117/Simulate-a-Windows-Service-using-ASP-NET-to-run-sc
这是我用来实现这种功能的东西。 http://www.codeproject.com/Articles/12117/Simulate-a-Windows-Service-using-ASP-NET-to-run-sc
回答by Jim Mischel
Any solution that depends on System.Timers.Timer
, System.Threading.Timer
, or any of the other timers that currently exist in the .NET Framework will fail in the face of Daylight Saving time changes. If you use any of those timers, you will have to do some polling.
任何依赖于System.Timers.Timer
、System.Threading.Timer
或当前存在于 .NET Framework 中的任何其他计时器的解决方案在夏令时更改时都将失败。如果您使用这些计时器中的任何一个,则必须进行一些轮询。
Windows has a Waitable Timerthat you can use, but it's not supported by any Framework class. I wrote a wrapper for it some years ago. The article I published is no longer available, but you can download the full source code from http://www.mischel.com/pubs/waitabletimer.zip
Windows 有一个可以使用的Waitable Timer,但它不受任何 Framework 类的支持。几年前我为它写了一个包装器。我发表的文章不再可用,但您可以从http://www.mischel.com/pubs/waitabletimer.zip下载完整的源代码
That said, if the only thing your program does is run once every day, or if the task it performs can be split off from the rest of the program, you're almost certainly better off with a scheduled task. And although I haven't ever used Quartz.NET, I have no problem recommending it based on the good reviews I've seen from people whose judgement I trust.
也就是说,如果您的程序所做的唯一一件事是每天运行一次,或者如果它执行的任务可以与程序的其余部分分开,那么您几乎可以肯定计划任务会更好。虽然我从未使用过 Quartz.NET,但根据我从我信任的人那里看到的好评推荐它,我没有问题。