Случайный генератор кистей - Как получить новый цвет каждый раз? [Дубликат]

Нет, невозможно скрыть консольное окно файла chromedriver.exe в привязках .NET, не изменяя исходный код привязки. Это рассматривается как функция привязок, так как очень легко увидеть, когда ваш код неправильно очистил ресурсы ChromeDriver, так как окно консоли остается открытым. В случае некоторых других языков, если ваш код неправильно очищает экземпляр ChromeDriver, вызывая метод quit() в объекте WebDriver, вы можете завершить процесс zombie chromedriver.exe, запущенный на вашем компьютере.

648
задан Taryn 22 March 2017 в 17:19
поделиться

7 ответов

Каждый раз, когда вы делаете new Random(), он инициализируется с использованием часов. Это означает, что в замкнутом цикле вы получаете одно и то же значение много раз. Вы должны сохранить один экземпляр Random и продолжать использовать Next в том же экземпляре.

//Function to get a random number 
private static readonly Random random = new Random(); 
private static readonly object syncLock = new object(); 
public static int RandomNumber(int min, int max)
{
    lock(syncLock) { // synchronize
        return random.Next(min, max);
    }
}

Изменить (см. Комментарии): зачем нам здесь lock?

В принципе, Next собирается изменить внутреннее состояние экземпляра Random. Если мы сделаем это в то же время из нескольких потоков, вы можете утверждать, что «мы только что сделали результат еще более случайным», но то, что мы фактически делаем потенциально нарушая внутреннюю реализацию, и мы могли бы также начать получать одинаковые числа из разных потоков, что может быть проблемой - и может и не быть. Однако гарантией того, что происходит внутри, является большая проблема; поскольку Random не дает никаких гарантий безопасности потока. Таким образом, существует два допустимых подхода:

  • синхронизировать, чтобы мы не обращались к нему в то же время из разных потоков
  • , используя разные Random экземпляры для потока

Либо может быть хорошо; но мьютексирование одного экземпляра из нескольких вызывающих абонентов в то же время просто требует неприятностей.

lock достигает первого (и более простого) этих подходов; однако другой подход может быть следующим:

private static readonly ThreadLocal<Random> appRandom
     = new ThreadLocal<Random>(() => new Random());

это то для потоковой, поэтому вам не нужно синхронизировать.

888
ответ дан David Storfer 16 August 2018 в 01:17
поделиться
  • 1
    Как правило, все статические методы должны быть потокобезопасными, так как трудно гарантировать, что несколько потоков не вызовут его одновременно. Это not , как правило, необходимо сделать instance (то есть нестатические) методы потокобезопасными. – Marc Gravell♦ 20 April 2009 в 13:32
  • 2
    @Florin - нет разницы re & quot; основанные на стеке " между двумя. Статические поля имеют такое же «внешнее состояние» и будут абсолютно разделены между вызывающими. С примерами существует хорошая вероятность, что разные потоки имеют разные экземпляры (общий шаблон). С помощью statics гарантируется , что все они разделяют (не включая [ThreadStatic]). – Marc Gravell♦ 20 April 2009 в 14:03
  • 3
    @MarcGravell с подходом ThreadLocal не все еще существует риск того, что два потока будут генерировать одну и ту же последовательность, если appRandom будет доступен одновременно этими двумя потоками? Или какой-то атрибут потока вносит вклад в сгенерированную последовательность? – Pero P. 9 August 2012 в 21:38
  • 4
    @Dan, если объект никогда не открывается публично: вы можете. (Очень теоретический) риск состоит в том, что какой-то другой поток блокирует его так, как вы этого не ожидали. – Marc Gravell♦ 1 February 2014 в 00:34
  • 5
    @smiron Очень вероятно, что вы просто используете случайную за пределами блокировки. Блокировка не препятствует доступу к тому, что вы запираете, - это просто гарантирует, что два оператора блокировки в одном экземпляре не будут запускаться одновременно. Таким образом, lock (syncObject) поможет только в том случае, если все random.Next() вызовы также находятся в lock (syncObject). Если описанный сценарий происходит даже при правильном использовании lock, то также возможно, что extreme имеет место в однопоточном сценарии (например, Random тонко разбит). – Luaan 21 April 2015 в 12:17

1) Как сказал Марк Гравелл, попробуйте использовать ОДИН случайный генератор. Всегда полезно добавить это в конструктор: System.Environment.TickCount.

2) Один совет. Предположим, вы хотите создать 100 объектов и предположите, что каждый из них должен иметь свой собственный генератор случайных чисел (удобно, если вы вычисляете НАГРУЗКИ случайных чисел за очень короткий промежуток времени). Если вы сделаете это в цикле (генерация 100 объектов), вы можете сделать это так (для обеспечения полной случайности):

int inMyRandSeed;

for(int i=0;i<100;i++)
{
   inMyRandSeed = System.Environment.TickCount + i;
   .
   .
   .
   myNewObject = new MyNewObject(inMyRandSeed);  
   .
   .
   .
}

// Usage: Random m_rndGen = new Random(inMyRandSeed);

Приветствия.

12
ответ дан 3 revs, 3 users 88% 16 August 2018 в 01:17
поделиться
  • 1
    Я бы переместил System.Environment.TickCount из цикла. Если он истекает, когда вы выполняете итерацию, у вас будет два элемента, инициализированных одним и тем же семенем. Другой вариант состоит в том, чтобы объединить элемент tickcount и i по-другому (например, System.Environment.TickCount & lt; 8 + i) – Dolphin 25 June 2009 в 20:03
  • 2
    Если я правильно понимаю: вы имеете в виду, что это может произойти, что & quot; System.Environment.TickCount + i & quot; может привести к тому же? – sabiland 26 June 2009 в 14:18
  • 3
    EDIT: Конечно, нет необходимости иметь TickCount внутри цикла. Виноват :). – sabiland 26 June 2009 в 14:19
  • 4
    По умолчанию конструктор Random() вызывает Random(Environment.TickCount) – Psychomatic Complexity 16 February 2017 в 17:29

Мой ответ из здесь :

Просто повторить правильное решение:

namespace mySpace
{
    public static class Util
    {
        private static rnd = new Random();
        public static int GetRandom()
        {
            return rnd.Next();
        }
    }
}

Итак, вы можете позвонить:

var i = Util.GetRandom();

повсюду.

Если для создания случайных чисел вам нужен только истинный статический метод без stateless, вы можете положиться на Guid.

public static class Util
{
    public static int GetRandom()
    {
        return Guid.NewGuid().GetHashCode();
    }
}

Это будет бит медленнее, но может быть гораздо более случайным , чем Random.Next, по крайней мере, из моего опыта.

Но не:

new Random(Guid.NewGuid().GetHashCode()).Next();

Невозможное создание объекта будет сделайте его медленнее, особенно в цикле.

И никогда:

new Random().Next();

Не только он медленнее (внутри цикла), его случайность ... ну не очень хорошая в соответствии с мне ..

30
ответ дан Community 16 August 2018 в 01:17
поделиться
  • 1
    Я не согласен с руководством. Класс Random реализует равномерное распределение. Это не так в Guid. Цель руководства состоит в том, чтобы быть уникальным неравномерно распределенным (и его реализация в большинстве случаев основана на некотором аппаратном / машинное свойство, которое противоположно ... случайности). – Askolein 31 March 2013 в 14:37
  • 2
    если вы не можете доказать единообразие генерации Guid, тогда неправильно использовать его как случайный (а Хэш будет еще одним шагом от однородности). Точно так же столкновения не являются проблемой: равномерность столкновения. Что касается поколения Guid, не находящегося на аппаратном уровне, я собираюсь в RTFM, мой плохой (любая ссылка?) – Askolein 31 March 2013 в 15:18
  • 3
    Существует два понимания «случайного»: 1. отсутствия шаблона или 2. отсутствия шаблона после эволюции, описываемой распределением вероятности (2, включенным в 1). Пример вашего руководства правильный в случае 1, а не в случае 2. В противоположность: Random класс соответствует случаю 2 (таким образом, случай 1 тоже). Вы можете заменить использование Random вашим Guid+Hash, если вы not в случае 2. Случай 1, вероятно, достаточно, чтобы ответить на вопрос, а затем ваш Guid+Hash работает нормально. Но ясно не сказано (ps: эта равномерная ) – Askolein 31 March 2013 в 18:33
  • 4
    @Askolein Просто для некоторых тестовых данных я запускаю несколько партий как Random, так и Guid.NewGuid().GetHashCode() через Ent ( fourmilab.ch/random ), и оба аналогично случайны. new Random(Guid.NewGuid().GetHashCode()) работает так же хорошо, как и с использованием синхронизированного «основного» Random для генерации семян для «ребенка» Random s .. Конечно, это зависит от того, как ваша система генерирует Guids - для моей системы они довольно случайны, а на других это может быть даже крипто-случайным. Таким образом, Windows или MS SQL кажется прекрасным в наши дни. Моно и / или мобильные устройства могут быть разными. – Luaan 21 April 2015 в 12:29
  • 5
    @EdB Как я уже говорил ранее в комментариях, в то время как Guid (большое число) является уникальным, GetHashCode Guid в .NET выводится из его строкового представления. Вывод довольно случайный по моему вкусу. – nawfal 3 August 2015 в 17:28

Решение Mark может быть довольно дорогостоящим, так как оно должно синхронизироваться каждый раз.

Мы можем обойти необходимость синхронизации, используя шаблон хранения, специфичный для потока:


public class RandomNumber : IRandomNumber
{
    private static readonly Random Global = new Random();
    [ThreadStatic] private static Random _local;

    public int Next(int max)
    {
        var localBuffer = _local;
        if (localBuffer == null) 
        {
            int seed;
            lock(Global) seed = Global.Next();
            localBuffer = new Random(seed);
            _local = localBuffer;
        }
        return localBuffer.Next(max);
    }
}

Измерьте две реализации, и вы увидите значительную разницу.

49
ответ дан Hans Malherbe 16 August 2018 в 01:17
поделиться
  • 1
    Замки очень дешевы, когда они не оспариваются ... и даже если оспаривать, я ожидаю, что теперь «сделают что-то с номером». кода, чтобы затмить стоимость блокировки в наиболее интересных сценариях. – Marc Gravell♦ 18 September 2009 в 16:57
  • 2
    Согласовано, это решает проблему блокировки, но разве это еще не очень сложное решение тривиальной проблемы: вам нужно написать строки '' two '' для генерации случайного числа вместо одного. Это действительно стоит сохранить чтение одной простой строки кода? – EMP 16 April 2010 в 00:07
  • 3
    +1 Использование дополнительного глобального экземпляра Random для получения семени - хорошая идея. Обратите также внимание на то, что код можно упростить, используя класс ThreadLocal<T>, введенный в .NET 4 (как Phil также написал ниже ). – Groo 9 May 2014 в 09:41

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

public String GenerateRandom(Random oRandom, int iLongitudPin)
{
    String sCharacters = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ123456789";
    int iLength = sCharacters.Length;
    char cCharacter;
    int iLongitudNuevaCadena = iLongitudPin; 
    String sRandomResult = "";
    for (int i = 0; i < iLongitudNuevaCadena; i++)
    {
        cCharacter = sCharacters[oRandom.Next(iLength)];
        sRandomResult += cCharacter.ToString();
    }
    return (sRandomResult);
}
1
ответ дан Marztres 16 August 2018 в 01:17
поделиться

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

public static class StaticRandom
{
    private static int seed;

    private static ThreadLocal<Random> threadLocal = new ThreadLocal<Random>
        (() => new Random(Interlocked.Increment(ref seed)));

    static StaticRandom()
    {
        seed = Environment.TickCount;
    }

    public static Random Instance { get { return threadLocal.Value; } }
}

Вы можете использовать затем статический случайный экземпляр с кодом, например

StaticRandom.Instance.Next(1, 100);
94
ответ дан Phil 16 August 2018 в 01:17
поделиться

Я предпочел бы использовать следующий класс для генерации случайных чисел:

byte[] random;
System.Security.Cryptography.RNGCryptoServiceProvider prov = new System.Security.Cryptography.RNGCryptoServiceProvider();
prov.GetBytes(random);
21
ответ дан Picrofo Software 16 August 2018 в 01:17
поделиться
  • 1
    Я не являюсь ни одним из избирателей, но помните, что стандартный PNRG действительно служит настоящей потребности, то есть иметь возможность воспроизводить последовательно последовательность из известного семени. Иногда чрезмерная стоимость истинного криптографического RNG слишком велика. И иногда требуется криптовальня. Лошади для курсов, так сказать. – Marc Gravell♦ 20 April 2009 в 13:35
  • 2
    Согласно документации этот класс является потокобезопасным, так что это что-то в его пользу. – Rob Church 26 April 2013 в 14:51
  • 3
    Какова вероятность того, что две случайные строки будут одинаковыми с этим? Если строка составляет всего 3 символа, я предполагаю, что это произойдет с большой вероятностью, но что, если длина 255 символов, возможно, имеет одну и ту же случайную строку или гарантируется, что это не может произойти из алгоритма? – Lyubomir Velchev 12 July 2016 в 13:03
Другие вопросы по тегам:

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