.NET, событие каждую минуту (на минуте). Действительно ли таймер является наилучшим вариантом?

Можно использовать sp_spaceused для определения размера таблицы или всей базы данных. При передаче имени таблицы оно возвращает пространство, использованное для той таблицы при вызове без аргумента оно дает пространство базы данных.

39
задан James World 30 May 2013 в 07:14
поделиться

11 ответов

Для запланированных задач я использую System.Threading.Timer (System .Threading.TimerCallback, object, int, int) с обратным вызовом, установленным на код, который я хочу выполнить, на основе интервала, который предоставляется в миллисекундах для значения периода.

0
ответ дан 27 November 2019 в 02:10
поделиться

Создание элемента управления Timer , который срабатывает каждую 1 секунду (и обычно не выполняет ничего, кроме простой проверки), добавит незначительных накладных расходов вашему приложению.

Просто сравните значение Environment.TickCount или DateTime.Now с последним сохраненным временем (предыдущий «минутный тик»), и вы получите достаточно точное решение. Разрешение этих двух значений времени составляет около 15 мсек, что должно быть достаточным для ваших целей.

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

8
ответ дан 27 November 2019 в 02:10
поделиться

Используйте таймер, который запускается каждую секунду (или миллисекунду, независимо от вашего порога точности), а затем закодируйте метод для запуска вашей функциональности тогда и только тогда, когда текущее время находится в пределах этого порога после точки «по минуте».

0
ответ дан 27 November 2019 в 02:10
поделиться

Выполнение небольшого количества кода, чтобы увидеть, изменилась ли минута один раз в секунду, не должно требовать много процессорного времени , и должно быть приемлемым.

2
ответ дан 27 November 2019 в 02:10
поделиться

Как насчет:

int startin = 60 - DateTime.Now.Second;
var t = new System.Threading.Timer(o => Console.WriteLine("Hello"), 
     null, startin * 1000, 60000);
29
ответ дан 27 November 2019 в 02:10
поделиться

А как насчет комбинации ответа Аквината и «опроса»: (извинения за смешение языков)

def waitForNearlyAMinute:
    secsNow = DateTime.Now.Second;
    waitFor = 55 - secsNow;
    setupTimer(waitFor, pollForMinuteEdge)

def pollForMinuteEdge:
    if (DateTime.Now.Second == 0):
        print "Hello, World!";
        waitForNearlyAMinute();
    else:
        setupTimer(0.5, pollForMinuteEdge)
0
ответ дан 27 November 2019 в 02:10
поделиться

В качестве альтернативы вы можете засыпать, чтобы приостановить выполнение до истечения времени ожидания, которое должно быть близко к желаемому времени. Это разбудит компьютер только по окончании спящего режима, так что вы сэкономите время ЦП и позволите ЦП отключаться между событиями обработки.

Это дает преимущество в изменении тайм-аута, чтобы он не смещался.

int timeout = 0;

while (true)  {
  timeout = (60 - DateTime.Now.Seconds) * 1000 - DateTime.Now.Millisecond;
  Thread.Sleep(timeout);

  // do your stuff here
}
1
ответ дан 27 November 2019 в 02:10
поделиться

Вы можете установить два таймера. Первоначальный таймер с коротким интервалом (возможно, чтобы срабатывать каждую секунду, но в зависимости от того, насколько точно второй таймер должен срабатывать в минуту).

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

void StartTimer()
{

  shortIntervalTimer.Interval = 1000;
  mainIntervalTimer.Interval = 60000; 

  shortIntervalTimer.Tick += 
    new System.EventHandler(this.shortIntervalTimer_Tick);
  mainIntervalTimer.Tick += 
    new System.EventHandler(mainIntervalTimer_Tick);

  shortIntervalTimer.Start();

}

private void shortIntervalTimer_Tick(object sender, System.EventArgs e)
{
  if (DateTime.Now.Second == 0)
    {
      mainIntervalTimer.Start();
      shortIntervalTimer.Stop();
    }
}

private void mainIntervalTimer_Tick(object sender, System.EventArgs e)
{
  // do what you need here //
}
1
ответ дан 27 November 2019 в 02:10
поделиться

А как насчет Quartz.NET ? Я думаю, что это хорошая основа для своевременных действий.

2
ответ дан 27 November 2019 в 02:10
поделиться

здание на ответ от Aquinas, который может дрейфовать и что не отмечает точно в минуту Одна секунда минуты:

static System.Timers.Timer t;

static void Main(string[] args)
{
    t = new System.Timers.Timer();
    t.AutoReset = false;
    t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
    t.Interval = GetInterval();
    t.Start();
    Console.ReadLine();
}

static double GetInterval()
{
    DateTime now = DateTime.Now;
    return ((60 - now.Second) * 1000 - now.Millisecond);
}

static void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    Console.WriteLine(DateTime.Now.ToString("o"));
    t.Interval = GetInterval();
    t.Start();
}

На моей коробке этот код последовательно входит в течение 0,02 с каждой минуты:

2010-01-15T16:42:00.0040001-05:00
2010-01-15T16:43:00.0014318-05:00
2010-01-15T16:44:00.0128643-05:00
2010-01-15T16:45:00.0132961-05:00
51
ответ дан 27 November 2019 в 02:10
поделиться

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

Класс построен с фиксированным временным шагом и поддерживает Start / Stop / Reset, Start / Stop / Start работает как операция возобновления. В этом отношении таймер похож на секундомер.

Реализация часов просто создаст класс с интервалом в 1 секунду и будет прослушивать событие. Однако будьте осторожны, это часы реального времени, если событие тика длится дольше, чем интервал для завершения, вы заметите, что часы будут пытаться догнать реальное время, это вызовет всплеск событий тика.

public class FixedStepDispatcherTimer
{
    /// <summary>
    /// Occurs when the timer interval has elapsed.
    /// </summary>
    public event EventHandler Tick;

    DispatcherTimer timer;

    public bool IsRunning { get { return timer.IsEnabled; } }

    long step, nextTick, n;

    public TimeSpan Elapsed { get { return new TimeSpan(n * step); } }

    public FixedStepDispatcherTimer(TimeSpan interval)
    {
        if (interval < TimeSpan.Zero)
        {
            throw new ArgumentOutOfRangeException("interval");
        }
        this.timer = new DispatcherTimer();
        this.timer.Tick += new EventHandler(OnTimerTick);
        this.step = interval.Ticks;
    }

    TimeSpan GetTimerInterval()
    {
        var interval = nextTick - DateTime.Now.Ticks;
        if (interval > 0)
        {
            return new TimeSpan(interval);
        }
        return TimeSpan.Zero; // yield
    }

    void OnTimerTick(object sender, EventArgs e)
    {
        if (DateTime.Now.Ticks >= nextTick)
        {
            n++;
            if (Tick != null)
            {
                Tick(this, EventArgs.Empty);
            }
            nextTick += step;
        }
        var interval = GetTimerInterval();
        Trace.WriteLine(interval);
        timer.Interval = interval;
    }

    public void Reset()
    {
        n = 0;
        nextTick = 0;
    }

    public void Start()
    {
        var now = DateTime.Now.Ticks;
        nextTick = now + (step - (nextTick % step));
        timer.Interval = GetTimerInterval();
        timer.Start();
    }

    public void Stop()
    {
        timer.Stop();
        nextTick = DateTime.Now.Ticks % step;
    }
}
5
ответ дан 27 November 2019 в 02:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: