Изменить переменную в бесконечном цикле

190
31 января 2019, 07:00

Нужно чтобы переменная proverkaTimera менялась в необходимом интервале времени с false на true и бесконечный цикл заходил бы в тело условия if (proverkaTimera)

Пробовал так и как в ответе ниже от trydex:

private void Algoritm()
{
    bool proverkaTimera = false;
    var timer = new DispatcherTimer();
    timer.Tick += Timer_Tick;
    timer.Interval = new TimeSpan(0, 0, 10, 0, 0);
    timer.Start();
    for (;;)
    {
       if (proverkaTimera)
       {
          ...
          proverkaTimera = false;
       }
       ...
    }
}
private void Timer_Tick(object sender, EventArgs e)
{
   proverkaTimera = true;
}

Ещё пробовал так, но в этом случае, откладывается выполнение остальной части когда пока пока не выполнится сам блок if.

private async void Algoritm()
{
    bool timerTick = false;
    for (;;)
    {
       timerTick = await Timer();
       if (timerTick)
       {
          ...
          timerTick = false;
       }
       ...
    }
}
private async Task<bool> Timer() 
{
        await Task.Delay(10000);
    return true;
}
Answer 1

Я не совсем понимаю, почему все зациклились :) на лямбдах и замыканиях. Замыкание, конечно, удобно в данном случае, но член класса тоже сработает. Гораздо хуже здесь то (если я правильно понимаю, как работает DispatcherTimer), что плотный цикл не даст вызваться событию таймера.

Используйте System.Threading.Timer вместо DispatcherTimer и

bool proverkaTimera = false;
private void Algoritm()
{
  proverkaTimera = false;
  ...
Answer 2

Как вам и подсказали в комментариях это можно сделать через лямбду, которая будет захватывать вашу переменную.

То есть вместо создания отдельного обработчика события таким образом:

timer.Tick += Timer_Tick; 

мы можем подписать лямбда-выражение вот так:

timer.Tick += (s, e) => { proverkaTimera = true;};

О замыканиях можете почитать здесь.

Также можно вместо локальной переменной сделать поле или свойство, тогда вы сможете к ней обращаться из вашего метода Timer_Tick в текущей реализации.

То есть ваш класс видоизменится до такого:

class Example
{
    private bool proverkaTimera;
    private void Algoritm()
    {
        proverkaTimera = false;
        //Остальной код
    }
    private void Timer_Tick(object sender, EventArgs e)
    {
        proverkaTimera = true;
    }
}
Answer 3

Нет никакого смысла в таймере, который всего лишь устанавливает переменную! Если вам нужно отслеживать наступление некоторого момента времени - то для этих целей существует класс CancellationTokenSource:

using (var cts = new CancellationTokenSource(TimeSpan.FromMinutes(10)))
{
    for(;;) 
    {
        if (cts.IsCancellationRequested)
        {
            // 10 минут прошли
        }
    }
}

Бонусом идет возможность дождаться наступления события

ctx.Token.WaitHandle.WaitOne();

а также получить сигнал о его наступлении используя метод Register.

READ ALSO
Почему не подключается xdebug.remote_enable?

Почему не подключается xdebug.remote_enable?

подключаю xdebug в использую php 72

248
Доступ к данным из другого потока

Доступ к данным из другого потока

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

158
Ошибки загрузки расширений PHP

Ошибки загрузки расширений PHP

Использую lamp сервер на ubuntu на php72

207
Как в ссылке на картинку добавить размер?

Как в ссылке на картинку добавить размер?

Вот есть такая ссылка в виде, но без парамразмера картинок

201