.NET4.0 WPF中随即函数的问题

viki117 2011-11-25 06:22:56
今天在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%是一样的,偶尔有个别不一样,不明白到底是怎么搞得,请教高手解答下....
...全文
125 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Icedmilk 2011-11-28
  • 打赏
  • 举报
回复
楼上几位真的用过Random么?

Random的无参构造方法就是以时间作为种子的,所以
Random r = new Random(DateTime.Now.Millisecond);没有任何意义,画蛇添足

楼主的原因是,所有的控件都同时创建,所以所有控件的timer都同时启动,然后所有的Timer的Elapsed都同时触发,然后所有的Random同时产生随机数,结果当然一样

要想取到不一样的随机数必须让种子不同
viki117 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qldsrx 的回复:]

Random是个伪随机类,你要传递种子才能做到不同的实例随机值不一样。
一般用时间做种子,例如:Random r = new Random(DateTime.Now.Millisecond);
[/Quote]
的确是如此,跳转到Random定义里面看了下Random的代码,原来Random还有怎么一回事~~多谢
qldsrx 2011-11-27
  • 打赏
  • 举报
回复
Random是个伪随机类,你要传递种子才能做到不同的实例随机值不一样。
一般用时间做种子,例如:Random r = new Random(DateTime.Now.Millisecond);
bdmh 2011-11-27
  • 打赏
  • 举报
回复
Random random = new Random();
这句话,不要循环,否则值一样,放到最外面,调用一次就够了
阿非 2011-11-27
  • 打赏
  • 举报
回复
Random random = new Random();
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();
定义到外面的做法是对的

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧