Edit @ Dublicate: я знаю, что небезопасное использование Thread не рекомендуется.Мой вопрос о том, почему, а не о том, является ли random потокобезопасным.Благодаря ответам, это помогло мне лучше понять это!
Я написал программу «трюк», которая должна отображать случайные символы со случайными цветами (для фона и для фона) в окне консоли с помощью Math.Random () и многопоточность.Для большей случайности я не сделал программу «поточно-безопасной».(Дополнительная информация: Первоначально я хотел, чтобы программа отображала Space-Invader в центре, я добился этого с помощью Thread-Safety, и я знаю, что многопоточность должна быть поточно-ориентированной, но это не тот вопрос, о котором идет речь)
Вывод выглядит так:
Функция программы такая: у меня есть массив, в котором все позиции (X / Y) с цветами и Char хранятся.У меня есть некоторые функции, которые изменяют этот массив, и у меня есть некоторые функции для отображения массива.Я также получил функцию для возврата случайных символов и одну для возврата случайных цветов.
Теперь вот что я не понимаю: иногда все работает, как описано, но иногда программа начинает отображать только! -Chars (восклицательный знак), но сохраняет случайные цвета и позиции:
В другой раз программа отображает цвета только черный и белый, но символы остаются случайными:
И иногда случается, что программа отображает только символы! -Черки и только черно-белые:
Что я могу сказать,следующее:
Моя функция «Получить случайный символ» выглядит следующим образом:
public static char GetChar()
{
return (char)randomChar.Next(33, 150);
}
! - Char - это Ascii-Char 33. Это означает, что если Программа застряла в Random-Char-Функция возвращает только самый низкий случайный символ (== 33 ==!)
Я получил что-то похожее для цветов.Я даю случайное число от 0 до 16 функции, чтобы вернуть Console-Color:
private ConsoleColor SetColor(char ColorIndex)
{
switch (ColorIndex)
{
case (char)1:
return ConsoleColor.Black;
case (char)2:
return ConsoleColor.Blue;
case (char)3:
return ConsoleColor.Cyan;
case (char)4:
return ConsoleColor.DarkBlue;
case (char)5:
return ConsoleColor.DarkCyan;
case (char)6:
return ConsoleColor.DarkGray;
case (char)7:
return ConsoleColor.DarkGreen;
case (char)8:
return ConsoleColor.DarkMagenta;
case (char)9:
return ConsoleColor.DarkRed;
case (char)10:
return ConsoleColor.DarkYellow;
case (char)11:
return ConsoleColor.Gray;
case (char)12:
return ConsoleColor.Green;
case (char)13:
return ConsoleColor.Magenta;
case (char)14:
return ConsoleColor.Red;
case (char)15:
return ConsoleColor.White;
case (char)16:
return ConsoleColor.Yellow;
default:
return ConsoleColor.Black;
}
}
//The call looks like that:
_Data[x, y, 1] = (char)random.Next(0, 16);
Я знаю, что random.Next (0, 16) вернет максимальное число как 15,и 15 - белый цвет в примере.Если я поменяю 15 на красный, программа будет отображаться красным вместо белого, когда программа застрянет:
Это означает: когда программа получилаЗастрявшая функция Random-Char всегда возвращает минимально возможное число (33), а функция Random-Color всегда возвращает максимально возможное число (15).
Вопрос : Почему это поведение?Почему это просто иногда, а не каждый раз?И почему это каждый раз после разного времени бега?Почему одна случайная функция всегда возвращает максимальное число, а другая всегда минимальное число?
Я предполагаю, что это из-за предсказания ЦП, но, как я уже сказал, это всего лишь предположение, и яИнтересно, как это работает, и почему это происходит с разными подходами (мин / макс).
Вот некоторые из моих кодов, при необходимости я мог бы опубликовать больше код:
//Program-Start after initialising some stuff:
public AnotherOne()
{
new Thread(DrawData).Start();
new Thread(DrawDataLR).Start();
new Thread(DrawDataRL).Start();
new Thread(DrawDataTD).Start();
new Thread(DrawDataDT).Start();
new Thread(ChangeData).Start();
ChangeData();
}
//Draw Data example for Left-Right:
private void DrawDataLR()
{
while (!_done)
{
DrawDataLeftRight();
Thread.Sleep(2);
}
}
private void DrawDataLeftRight()
{
for (int x = 0; x < _Width - 1; x++)
{
for (int y = 0; y < _Height - 1; y++)
{
Console.SetCursorPosition(x, y);
Console.BackgroundColor = SetColor(_Data[x, y, 1]);
Console.ForegroundColor = SetColor(_Data[x, y, 2]);
Console.WriteLine(_Data[x, y, 0]);
}
}
}
//Draw Data Function:
private void DrawData()
{
Random next = new Random();
int x = 1;
while (!_done)
{
x = next.Next(1, 5);
switch (x)
{
case 1:
DrawDataLeftRight();
break;
case 2:
DrawDataTopDown();
break;
case 3:
DrawDataRightLeft();
break;
case 4:
DrawDataDownTop();
break;
}
}
}
//Change Data Function with "stripes" as Example:
private void ChangeData()
{
int x = 100;
while (!_done)
{
FillRandomFeld();
Thread.Sleep(x);
ClearChar();
Thread.Sleep(x);
SetColor();
Thread.Sleep(x);
Stripes();
Thread.Sleep(x);
SetChar();
Thread.Sleep(x);
OtherStripes();
Thread.Sleep(x);
x = randomX.Next(0, 100);
}
}
private void Stripes()
{
char colr = (char)random.Next(0, 16);
for (int x = 0; x < _Width - 1; x += 4)
{
for (int y = 0; y < _Height - 1; y++)
{
if (_Data[x, y, 3] != (char)1)
{
_Data[x, y, 1] = colr;
_Data[x, y, 2] = colr;
}
}
}
}