今天在wpf中做了一个控件,使用随机函数来获取一个值,更新一个进度条的数值,然后在主界面上实例了很多个,运行后发现,每个控件出来的随机值几乎一样, System.Timers.Timer timer;
System.Timers.Timer timer_change; public UserProssess()
{
InitializeComponent();
} //开始计时器
public void loadInfo()
{
timer = new System.Timers.Timer();
timer_change = new System.Timers.Timer();
timer_change.Interval = 10;
timer_change.Elapsed += new System.Timers.ElapsedEventHandler(timer_change_Elapsed);
timer.Interval = 1000;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Start();
} //停止计时器
public void stopInfo()
{
timer.Stop();
timer_change.Stop();
} int To_prossess = 0;
int Form_prossess = 0;
bool isAdd = false;
static object oo = new object(); //计时器1,用来循环获取随机数,并开启界面更新计时器
public void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
this.Dispatcher.BeginInvoke(new Action(() =>
{
timer_change.Stop();
lock (oo)
{
Random random = new Random();
To_prossess = random.Next(0, 100);
System.Threading.Thread.Sleep(12);
}
if (To_prossess > Form_prossess)
isAdd = true;
else if (To_prossess < Form_prossess)
isAdd = false;
else
return;
timer_change.Start();
}),
null);
}
//计时器2,10毫秒为单位,更新进度条,每次更新1%
public void timer_change_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (Form_prossess == To_prossess)
{
timer_change.Stop();
return;
}
if (isAdd)
Form_prossess++;
else
Form_prossess--;
this.Dispatcher.BeginInvoke(new Action(() =>
{
textBlock1.Text = Form_prossess.ToString() + "%";
rectangle1.Width = Form_prossess; int a = (int)((255.0 / 100.0) * Form_prossess);
textBlock1.Foreground = new SolidColorBrush(Color.FromRgb((byte)a, (byte)100, (byte)0));
rectangle1.Fill = new SolidColorBrush(Color.FromRgb((byte)a, (byte)100, (byte)0));
}),
null);
}
上面的代码就是2个计时器,一个1秒钟随机一个0-100的数字,另一个计时器10毫秒一次作进度条的修改lock (oo)
{
Random random = new Random();
To_prossess = random.Next(0, 100);
System.Threading.Thread.Sleep(12);
}注意这里,最后我没办法,强制获取随机后休眠,并lock一个静态object,保证单例,才基本可以保证随机出来的值不会相近,如果把上面的代码改成To_prossess = random.Next(0, 100);Random random = new Random();的定义做到外面去,不做休眠,结果出来的效果是,每个控件每次随机出来的数值90%是一样的,偶尔有个别不一样,不明白到底是怎么搞得,请教高手解答下....
System.Timers.Timer timer_change; public UserProssess()
{
InitializeComponent();
} //开始计时器
public void loadInfo()
{
timer = new System.Timers.Timer();
timer_change = new System.Timers.Timer();
timer_change.Interval = 10;
timer_change.Elapsed += new System.Timers.ElapsedEventHandler(timer_change_Elapsed);
timer.Interval = 1000;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Start();
} //停止计时器
public void stopInfo()
{
timer.Stop();
timer_change.Stop();
} int To_prossess = 0;
int Form_prossess = 0;
bool isAdd = false;
static object oo = new object(); //计时器1,用来循环获取随机数,并开启界面更新计时器
public void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
this.Dispatcher.BeginInvoke(new Action(() =>
{
timer_change.Stop();
lock (oo)
{
Random random = new Random();
To_prossess = random.Next(0, 100);
System.Threading.Thread.Sleep(12);
}
if (To_prossess > Form_prossess)
isAdd = true;
else if (To_prossess < Form_prossess)
isAdd = false;
else
return;
timer_change.Start();
}),
null);
}
//计时器2,10毫秒为单位,更新进度条,每次更新1%
public void timer_change_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (Form_prossess == To_prossess)
{
timer_change.Stop();
return;
}
if (isAdd)
Form_prossess++;
else
Form_prossess--;
this.Dispatcher.BeginInvoke(new Action(() =>
{
textBlock1.Text = Form_prossess.ToString() + "%";
rectangle1.Width = Form_prossess; int a = (int)((255.0 / 100.0) * Form_prossess);
textBlock1.Foreground = new SolidColorBrush(Color.FromRgb((byte)a, (byte)100, (byte)0));
rectangle1.Fill = new SolidColorBrush(Color.FromRgb((byte)a, (byte)100, (byte)0));
}),
null);
}
上面的代码就是2个计时器,一个1秒钟随机一个0-100的数字,另一个计时器10毫秒一次作进度条的修改lock (oo)
{
Random random = new Random();
To_prossess = random.Next(0, 100);
System.Threading.Thread.Sleep(12);
}注意这里,最后我没办法,强制获取随机后休眠,并lock一个静态object,保证单例,才基本可以保证随机出来的值不会相近,如果把上面的代码改成To_prossess = random.Next(0, 100);Random random = new Random();的定义做到外面去,不做休眠,结果出来的效果是,每个控件每次随机出来的数值90%是一样的,偶尔有个别不一样,不明白到底是怎么搞得,请教高手解答下....
To_prossess = random.Next(0, 100);
System.Threading.Thread.Sleep(12);
=>
Random random = new Random();
System.Threading.Thread.Sleep(12);
To_prossess = random.Next(0, 100);随机数的种子和时间有关系。把Random random = new Random();
定义到外面的做法是对的
这句话,不要循环,否则值一样,放到最外面,调用一次就够了
一般用时间做种子,例如:Random r = new Random(DateTime.Now.Millisecond);
Random r = new Random(DateTime.Now.Millisecond);没有任何意义,画蛇添足楼主的原因是,所有的控件都同时创建,所以所有控件的timer都同时启动,然后所有的Timer的Elapsed都同时触发,然后所有的Random同时产生随机数,结果当然一样要想取到不一样的随机数必须让种子不同