Нет, невозможно скрыть консольное окно файла chromedriver.exe в привязках .NET, не изменяя исходный код привязки. Это рассматривается как функция привязок, так как очень легко увидеть, когда ваш код неправильно очистил ресурсы ChromeDriver, так как окно консоли остается открытым. В случае некоторых других языков, если ваш код неправильно очищает экземпляр ChromeDriver, вызывая метод quit()
в объекте WebDriver, вы можете завершить процесс zombie chromedriver.exe, запущенный на вашем компьютере.
Каждый раз, когда вы делаете 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());
это то для потоковой, поэтому вам не нужно синхронизировать.
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);
Приветствия.
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();
Не только он медленнее (внутри цикла), его случайность ... ну не очень хорошая в соответствии с мне ..
Random
класс соответствует случаю 2 (таким образом, случай 1 тоже). Вы можете заменить использование Random
вашим Guid+Hash
, если вы not i> в случае 2. Случай 1, вероятно, достаточно, чтобы ответить на вопрос, а затем ваш Guid+Hash
работает нормально. Но ясно не сказано (ps: эта равномерная )
– Askolein
31 March 2013 в 18:33
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
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);
}
}
Измерьте две реализации, и вы увидите значительную разницу.
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);
}
Для удобства повторного использования во всем приложении может помочь статический класс.
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);
Я предпочел бы использовать следующий класс для генерации случайных чисел:
byte[] random;
System.Security.Cryptography.RNGCryptoServiceProvider prov = new System.Security.Cryptography.RNGCryptoServiceProvider();
prov.GetBytes(random);
ThreadLocal
не все еще существует риск того, что два потока будут генерировать одну и ту же последовательность, еслиappRandom
будет доступен одновременно этими двумя потоками? Или какой-то атрибут потока вносит вклад в сгенерированную последовательность? – Pero P. 9 August 2012 в 21:38lock (syncObject)
поможет только в том случае, если все i>random.Next()
вызовы также находятся вlock (syncObject)
. Если описанный сценарий происходит даже при правильном использованииlock
, то также возможно, что extreme i> имеет место в однопоточном сценарии (например,Random
тонко разбит). – Luaan 21 April 2015 в 12:17