我正在构建类似验证码的功能,我有一种绘制随机线的方法
private Graphics DrawRandomLines(Graphics g)
{
SolidBrush green = new SolidBrush(Color.Green);
int count = 0;
for (int i = 0; i < 20; i++)
{
g.DrawLines(new Pen(green, 2), GetRandomPoints());
count++;
}
return g;
}
当我启动网络应用程序时,问题是我的图形上只画了一行。但是当我在调试模式下启动时,循环工作正在进行,并且我将绘制所有20条线。
这是GetRandomPoints
private Point[] GetRandomPoints()
{
Random rand = new Random();
Point[] points = { new Point(rand.Next(0, 100),
rand.Next(0, 30)),
new Point(rand.Next(0, 100),
rand.Next(0, 30)) };
return points;
}
答案 0 :(得分:4)
问题在于你为20个点中的每个点实例化一个新的Random
对象。时间差很小,“随机”值不够随机。当您调试应用程序时,“暂停”以检查值并且系统时钟前进,因此新的Random
对象具有与前一个不同的种子。最重要的是,你的20条线被绘制,只是它们具有相同的位置,即它们被绘制在彼此之上。
更改为:
private Graphics DrawRandomLines(Graphics g)
{
SolidBrush green = new SolidBrush(Color.Green);
int count = 0;
//instantiate only one time
Random rand = new Random();
//same here
Pen greenPen = new Pen(green, 2);
for (int i = 0; i < 20; i++)
{
g.DrawLines(greenPen, GetRandomPoints(rand));
count++;
}
return g;
}
private Point[] GetRandomPoints(Random rand)
{
Point[] points = { new Point(rand.Next(0, 100),
rand.Next(0, 30)),
new Point(rand.Next(0, 100),
rand.Next(0, 30)) };
return points;
}
答案 1 :(得分:1)
每次调用GetRandomPoints时,该函数都会创建一个新的Random对象,该对象将使用当前时钟时间进行播种。
当你在Release模式下运行时,对GetRandomPoints的20次调用发生得如此之快,以至于所有20个Random对象都以完全相同的值播种,因此它们都产生相同的“随机”数字。你正在画二十行 - 他们只是完全相同!
但是,在调试模式下运行时,所有添加的调试代码都会使事情变慢,以至于Random对象获得不同的种子值,因此生成的随机数不同。
要解决这个问题,您需要创建一个可以重复使用的单个Random对象,从而创建二十个不同的Random对象(这些对象可能会使它们都被相同地播种)。要做到这一点,不要在GetRandomPoints中创建Random对象 - 而是将其作为参数,并在DrawRandomLines中创建它。