Подтвердить что ты не робот

С#: как начать поток в определенное время

Как начать фоновый поток в определенное время суток, скажем, 16:00?

Итак, когда приложения запустится, поток будет ждать до этого времени. Но если приложение запускается после этого времени, поток будет работать сразу.

ThreadPool.QueueUserWorkItem(MethodtoRunAt1600);

4b9b3361

Ответ 1

Вы можете настроить таймер на 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
}

Затем настройте его, используя

SetUpTimer(new TimeSpan(16, 00, 00));

Изменить: сохранить ссылку на таймер, поскольку он предназначен для сбора мусора независимо от того, включен ли таймер.

Ответ 2

Я бы использовал библиотеку планирования заданий, например Quartz, или просто создаю консольное приложение и запускаю его с помощью планировщика задач Windows в определенное время день.

Почему бы просто не использовать System.Timers.Timer?

  • Таймеры не имеют механизма сохранения.
  • Таймеры имеют негибкое планирование (только для установки времени начала и повтора, ничего не зависит от дат, времени суток и т.д.
  • Таймеры не используют пул потоков (один поток за таймер)
  • Таймеры не имеют реальных схем управления - вам придется написать свой собственный механизм для запоминания, организации и поиска ваших задач по имени, e

Ответ 3

Любое решение, зависящее от System.Timers.Timer, System.Threading.Timer или любого другого таймера, которое в настоящее время существует в .NET Framework, не будет выполнено с учетом изменений времени перехода на летнее время. Если вы используете какой-либо из этих таймеров, вам нужно будет сделать несколько опросов.

Windows имеет Ожидаемый таймер, который вы можете использовать, но не поддерживается никаким классом Framework. Несколько лет назад я написал обертку. Опубликованная статья больше не доступна, но вы можете загрузить полный исходный код из http://www.mischel.com/pubs/waitabletimer.zip

Тем не менее, если единственное, что делает ваша программа, запускается один раз в день, или если выполняемая задача может быть отколота от остальной части программы, вам почти наверняка будет лучше с запланированной задачей. И хотя я никогда не использовал Quartz.NET, у меня нет проблем с рекомендацией, основанной на хороших отзывах, которые я видел от людей, чье решение я доверяю.

Ответ 4

вы можете сделать это с помощью таймера:

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;
    }
}

Ответ 5

Если вы ищете что-то "быстрое и грязное"... тогда вы можете просто начать свой поток в пуле потоков и "подождать" в нужное время.

// By the way, this code would be *INSIDE* of the background thread. That what
// the sentence above says, but apparently we devs only read code :)
while (DateTime.Now.TimeOfDay < myDesiredStartTime)
{
    Thread.Sleep(1000);
}

Ответ 6

Вот простой способ запланировать метод, который будет вызываться один раз, либо сразу, либо в 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); 
} 

Ответ 7

Можем ли мы так использовать?

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();
}

Затем проверьте каждую минуту.

void timer_Tick(object sender, EventArgs e)
{
    if (DateTime.Now.Hour == 16)
    {
        // Start your task
    }
}

Ответ 8

Очень простое решение:

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()
}

Ответ 9

1- Вызов приложения из другого процесса

System.Diagnostics.Process.Start("CMD MyApplication.exe", "/C TIME 16:00");

2- Используйте Timer и каждую минуту проверяйте текущее время.

3- Обработать событие изменения времени Windows в вашем приложении и каждый раз также проверять текущее время больше информации:

http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.timechanged%28v=vs.100%29.aspx

Я надеюсь, что один из thoese поможет вам.