Баг Random или нельзя делать Random в цикле for?

  • Автор темы Автор темы The_vAe
  • Дата начала Дата начала

The_vAe

Client
Регистрация
30.05.2019
Сообщения
3 759
Реакции
1 493
Баллы
113
Доброго времени. Есть снипет:
C#:
Развернуть Свернуть Копировать
for (int i = 0; i < 10; i++)
{

project.SendToLog(Convert.ToString(new Random().Next(1, 100)), ZennoLab.InterfacesLibrary.Enums.Log.LogType.Info, true,
        ZennoLab.InterfacesLibrary.Enums.Log.LogColor.Default);
}

Мне казалось, он должен 10 раз выдать в лог 10 разных рандомных цифр, но как оказалось - он выдает 10 одинаковых цифр. Не совсем понятно почему, если мы ведь каждый проход в цикле обращаемся как создать - новый рандом, разве нет?

94114
 
Доброго времени. Есть снипет:
C#:
Развернуть Свернуть Копировать
for (int i = 0; i < 10; i++)
{

project.SendToLog(Convert.ToString(new Random().Next(1, 100)), ZennoLab.InterfacesLibrary.Enums.Log.LogType.Info, true,
        ZennoLab.InterfacesLibrary.Enums.Log.LogColor.Default);
}

Мне казалось, он должен 10 раз выдать в лог 10 разных рандомных цифр, но как оказалось - он выдает 10 одинаковых цифр. Не совсем понятно почему, если мы ведь каждый проход в цикле обращаемся как создать - новый рандом, разве нет?

Посмотреть вложение 94114
Это не баг.
Вам нужно создать объект Random до цикла, а не в цикле
 
  • Оценить
Реакции: The_vAe
C#:
Развернуть Свернуть Копировать
Random rnd = new Random();
for (int i = 0; i < 10; i++)
{

project.SendToLog(Convert.ToString(rnd.Next(1, 100)), ZennoLab.InterfacesLibrary.Enums.Log.LogType.Info, true,
        ZennoLab.InterfacesLibrary.Enums.Log.LogColor.Default);
}
 
Так, же можно сделать паузу

C#:
Развернуть Свернуть Копировать
for (int i = 0; i < 10; i++)
{

project.SendToLog(Convert.ToString(new Random().Next(1, 100)), ZennoLab.InterfacesLibrary.Enums.Log.LogType.Info, true,
        ZennoLab.InterfacesLibrary.Enums.Log.LogColor.Default);
    Thread.Sleep(1);
}
 
Это псевдорандом.
таким образом new Random() он всегда генерируется одинаковый. и последовательность у него будет всегда одинаковая во всех потоках.
Выше показали как получить последовательность, а вот если надо получить другую последовательность, отличную от других потоков, то надо использовать его перегрузку
94116


можно в качестве нового Seed использовать текущие тики

C#:
Развернуть Свернуть Копировать
            Thread.Sleep(1);
            int seed = (int) DateTime.Now.Ticks & 0x0000FFFF;
            Random rnd = new Random(seed);
            return rnd.Next(start, end);
 
  • Оценить
Реакции: The_vAe и volody00
Так, же можно сделать паузу

C#:
Развернуть Свернуть Копировать
for (int i = 0; i < 10; i++)
{

project.SendToLog(Convert.ToString(new Random().Next(1, 100)), ZennoLab.InterfacesLibrary.Enums.Log.LogType.Info, true,
        ZennoLab.InterfacesLibrary.Enums.Log.LogColor.Default);
    Thread.Sleep(1);
}

Т.е. цикл не дает возможность новой генерации?
Генерация зависит от текущего время, а у вас генерируется мгновенно.Поэтому и повторы.
Если сделаете паузу хоть на мс, то повторов не будет
 
Доброго времени. Есть снипет:
C#:
Развернуть Свернуть Копировать
for (int i = 0; i < 10; i++)
{

project.SendToLog(Convert.ToString(new Random().Next(1, 100)), ZennoLab.InterfacesLibrary.Enums.Log.LogType.Info, true,
        ZennoLab.InterfacesLibrary.Enums.Log.LogColor.Default);
}

Мне казалось, он должен 10 раз выдать в лог 10 разных рандомных цифр, но как оказалось - он выдает 10 одинаковых цифр. Не совсем понятно почему, если мы ведь каждый проход в цикле обращаемся как создать - новый рандом, разве нет?

Посмотреть вложение 94114
Ну такое делать в принципе не надо, вы вызываете объект класса рандом по слабой ссылке , в цикле, таким образом при каждой итерации создается анонимный класс, что нагружает систему.

У меня кстати в vs все нормально работает.
2022-07-07_13-49-53.png
Но лучше все таки создавать экземпляр класса нормальный.
 
Ну такое делать в принципе не надо, вы вызываете объект класса рандом по слабой ссылке без выделения места на куче, в цикле, таким образом при каждой итерации создается анонимный класс, что нагружает систему.

У меня кстати в vs все нормально работает.
Посмотреть вложение 94118
Но лучше все таки создавать экземпляр класса нормальный.
а работа в визуал студии немного отличается от работы в кубике C# , тем более в консоли. зенка вносит свои реалии в работу кода.
 
На будущее ещё стоит учитывать, что рандом нужно синхронизировать, при работе в многопотоке.
 
  • Оценить
Реакции: Sho и BAZAg
а работа в визуал студии немного отличается от работы в кубике C# , тем более в консоли. зенка вносит свои реалии в работу кода.
Реально, провел тесты так сказать) проблема точно в слабой ссылке. Мне кажется что это уже к разрабам вопрос, почему зенка слабые ссылки не переваривает в таком виде.
2022-07-07_14-01-39.png2022-07-07_14-01-12.png
 
Ну такое делать в принципе не надо, вы вызываете объект класса рандом по слабой ссылке , в цикле, таким образом при каждой итерации создается анонимный класс, что нагружает систему.

У меня кстати в vs все нормально работает.
Посмотреть вложение 94118
Но лучше все таки создавать экземпляр класса нормальный.
У вас вообще .net 5.0... Это уже даже не Core.
 
Перевел на кор 3.1, все так же нормально работает
Тестируйте как минимум под framework 4.6.2 и не под отладкой, она замедляет выполнение - это скрывает проблему.
Собирать надо под Release, а exe запускать самому.
это как, если не секрет ?
Через lock.
Для удобства, можно свой объект-обёртку написать, содержащий рандом и lock.
 
  • Оценить
Реакции: Sho

Кто просматривает тему: (Всего: 0, Пользователи: 0, Гости: 0)