過去我已經使用了一種叫做ManualResetEvent的東西,並取得了很大的成功。假設您知道運行代碼的確切時間,那麼您將能夠計算預計運行時間(TTR),並且應該在第一次運行中配置後續運行。
partial class SomeService : ServiceBase
{
private ManualResetEvent stop = new ManualResetEvent(false);
private List<DateTime> times;
private int idxDT = 0;
public SomeService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
this.stop.Reset();
//implement you logic to calculate miliseconds to desired first run time
int miliseconds_to_run = 1;
ThreadPool.RegisterWaitForSingleObject(this.stop,
new WaitOrTimerCallback(ThreadFunc),
null,
miliseconds_to_run,
true);
}
private void ThreadFunc(object _state, bool _timedOut)
{
if (_timedOut)
{
if(this.times == null)
{
//get a list of times to run, store it along with the index of current TTR
this.times = new List<DateTime>();
}
int miliseconds_to_run = (this.times[this.idxDT++] - DateTime.Now).Miliseconds;
ThreadPool.RegisterWaitForSingleObject(this.stop,
new WaitOrTimerCallback(ThreadFunc),
null,
miliseconds_to_run,
true);
}
}
protected override void OnStop()
{
this.stop.Set();
}
}
當然,這很大程度上取決於您的工作開始時間的精確程度。 ThreadPool類將向操作系統發送一個線程調用請求,然後它將等待來自該線程池的下一個可用線程。在一些有很多線程的進程中,這可能會導致線程匱乏,您的確切時間將會延遲。
你也可以嘗試從.NET創建任務計劃程序作業,但我從來沒有這樣做過。
計劃任務? –
可能重複的[如何設置計時器在特定時間在c#中執行](http://stackoverflow.com/questions/21299214/how-to-set-timer-to-execute-at-specific-time-in- c-sharp) – itsme86
對於這個問題,唯一正確的答案是「你不能」,因爲由於操作系統的限制,你無法將任何事情調度到毫秒級。話雖如此,爲什麼子彈1和2會阻止你使用'System.Timers.Timer'? –