в моей программе есть функция,которая должна выполняться только в определенное время(дд/мм/гггг).Пользователь вводит дату,и только в это время функция выполняеться. как реализовать таймер?
Ответ
Одним из миллиона способов. Например, так:
async Task ExecuteAfter(DateTime when, Action function)
{
DateTime now = DateTime.Now;
if (when > now)
await Task.Delay(when - now);
function();
}
Другой метод:
DateTime now = DateTime.Now;
if (when <= now)
{
function();
}
else
{
var milliseconds = (when - now).TotalMilliseconds;
var timer = new System.Timers.Timer(milliseconds) { AutoReset = false };
timer.Elapsed += (o, args) => { function(); timer.Stop(); timer.Dispose(); };
// если вы пишете на WinForms, можете указать ещё
// timer.SynchronizingObject =
Ещё один:
DateTime now = DateTime.Now;
if (when <= now)
{
function();
}
else
{
System.Threading.Timer timer = null;
timer = new System.Threading.Timer(
o => { function(); timer.Dispose(); },
null,
when - now,
TimeSpan.Zero);
}
Ещё один подход — использование синхронизационных примитивов и ожидание с таймаутом события, которое никогда не наступит. Например, при помощи семафора:
DateTime now = DateTime.Now;
if (when > now)
using (var sema = new SemaphoreSlim(0))
sema.Wait(when - now);
function();
(Не рекомендуется, блокирует текущий поток!)
Ещё один метод, использование потоков + Sleep. Не рекомендуется, т. к. блокирует поток, а это ненужный расход ресурсов. Наихудший метод — блокирование текущего потока:
DateTime now = DateTime.Now;
if (when > now)
Thread.Sleep(when - now);
function();
Чуть лучше идея с выгрузкой в отдельный поток:
new Thread(() =>
{
DateTime now = DateTime.Now;
if (when > now)
Thread.Sleep(when - now);
function();
}) { IsBackground = true }.Start();
Ещё чуть-чуть лучше использовать thread pool (но всё равно плохо):
ThreadPool.QueueUserWorkItem(o =>
{
DateTime now = DateTime.Now;
if (when > now)
Thread.Sleep(when - now);
function();
});
Комментариев нет:
Отправить комментарий