@rinnn

Остановить проверку if на время?

Есть несколько int, которые получают постоянно получают случайные значения.
Например в эту секунду
int 1 = 100
int 2 = 50
int 3 = 150

_________________________________________________________________________________
Пример цикла
while (true)
{
    if (int1 > 20)
        {
            //код
            System.Threading.Thread.Sleep(200000);
        }   
    
    if (int2 > 400)
        {
            //код
            System.Threading.Thread.Sleep(200000);
        }

    if (int3 > 300)
        {
            //код
            System.Threading.Thread.Sleep(200000);
        }
}

Цикл должен идти всегда, НО если после того, как условие int1 > 20 выполнится, остальные проверяться, конечно не будут, т.к. поток спит. Таких int очень много, вариант с отдельными потоками не подойдет. Я только учусь, жду вашего совета, заранее спасибо.
UPD: Пауза нужна обязательно, после выполения кода внутри условия
  • Вопрос задан
  • 652 просмотра
Решения вопроса 3
borisdenis
@borisdenis
Ленив и вреден...
Немного не понятно что нужно получить, если надо проверить все условия, выполнить те, которые подходят и потом "поспать" то лучше как то так (но потоки адекватнее)

while (true)
{
    if (int1 > 20)
        {
            //код
        }   
    
    if (int2 > 400)
        {
            //код
        }

    if (int3 > 300)
        {
            //код
        }
   System.Threading.Thread.Sleep(200000);
}
Ответ написан
Комментировать
mashletov
@mashletov
Math.random()
Таких int очень много, вариант с отдельными потоками не подойдет.

1) Вообще-то это единственное адекватное решение. Если потоков много, то делайте Пул из нескольких. Если весь лимит занят, то будет ожидание пока освободится.

2) Что-то мне подсказывает что ваш System.Threading.Thread.Sleep(200000) какой-то адский костыль, незменимость которого вы сами себе придумали. Зачем это вам?
Ответ написан
Комментировать
mindtester
@mindtester Куратор тега C#
http://iczin.su/hexagram_48
из вопроса пока не понятно что вы хотите? но для начала:
-
после того, как условие int1 > 20 выполнится, остальные проверяться, конечно не будут,
во первых будут, да задача "поспит", но (upd) потом значения проверяться все равно будут
- если вы хотите манипулировать прохождением цикла, используйте операторы
continue
и/или
breack

пример
while (true)
{
    if (int1 > 20)
        {
            //код
            System.Threading.Thread.Sleep(200000);
            continue;
        }   
        // ...
}

вот в этом случае, остальные проверки не будут выполнятся, и цикл уйдет на следующий виток

можно еще манипулировать порядком проверки значений, а можно вообще использовать case

но не зная конечной цели, дать более внятный совет невозможно
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Namynnuz
Тебе просто нужно добавить в условие проверки соответствующий тайм-аут. Например, это можно сделать так:
public class Checker {
    const double _stdDelta = 10.0d;
    Dictionary<string, DateTime> _dictionary = new Dictionary<string, DateTime>();

    bool check( string input, double? delta = null ) {
        if ( !_dictionary.ContainsKey( input ) ) {
            _dictionary.Add( input, DateTime.Now );
            return true;
        }

        var d = delta.HasValue ? delta.Value : _stdDelta;

        if ( ( DateTime.Now - _dictionary[input] ).TotalSeconds > d ) {
            _dictionary[input] = DateTime.Now;
            return true;
        }

        return false;
    }

    public void CheckConditionByIfs( int condition ) {
        if ( condition > 100 && check( "second_condition", 20.0d ) ) {
            Console.WriteLine( "Second_condition met, custom timeout set." );
        } else if ( condition > 20 && check( "first_condition" ) ) {
            Console.WriteLine( "First_condition met, standard timeout set." );
        } else {
            Console.WriteLine( "Nothing." );
        }
    }

    public void CheckConditionBySwitch( int condition ) {
        switch ( condition ) {
            case var _ when condition > 100 && check( "second_condition", 20.0d ):
                Console.WriteLine( "Second_condition met, custom timeout set." );
                return;
            case var _ when condition > 20 && check( "first_condition" ):
                Console.WriteLine( "First_condition met, standard timeout set." );
                return;
        }
        Console.WriteLine( "Nothing." );
    }
}

Пример использования:
var rnd = new Random();
var values = new int[] { 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 100, 150, 200 };
var c = new Checker();
int cnd;

while ( true ) {
    cnd = values[rnd.Next( values.Length )];
    Console.WriteLine( cnd );

    if ( rnd.Next( 100 ) > 50 )
        c.CheckConditionBySwitch( cnd );
    else
        c.CheckConditionByIfs( cnd );

    Thread.Sleep( 1500 );
}

Поясню. В C# 7.0 появилось зарождение Pattern Matching'а, который ты можешь наблюдать в CheckConditionBySwitch (в плане логики выполнения он ничем не отличается от CheckConditionByIfs, поэтому они потом выбираются случайно). По выходу C# 8.0 это будет вполне себе полноценный вариант, как в Nemerle, Kotlin или F#, поэтому к switch и его новому синтаксису стоит присмотреться уже сейчас. Вообще, использование Thread.Sleep для таймаута — дурной тон. Он неточен и выдаёт что-то примерно около, когда у системы появятся свободные ресурсы. Гораздо лучше воспользоваться каким-нить TimeSpan, как таймером. Ну да ладно.
В данном примере условия для разных веток разделяются, путём назначения им по уникальному стринговому ключу текущей даты-времени (ключ может содержать, в принципе, что угодно). После этого для соотв. ключа ты проверяешь, не пришло ли время обновить значение по ключу и вернуть true, для входа в ветку кода. Если у тебя однозначно ограниченные варианты, то, вероятно, стоило бы создать enum, вместо string и проверять\передавать уже его.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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