今天在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%是一样的,偶尔有个别不一样,不明白到底是怎么搞得,请教高手解答下....

解决方案 »

  1.   

    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();
    定义到外面的做法是对的
      

  2.   

    Random random = new Random();
    这句话,不要循环,否则值一样,放到最外面,调用一次就够了
      

  3.   

    Random是个伪随机类,你要传递种子才能做到不同的实例随机值不一样。
    一般用时间做种子,例如:Random r = new Random(DateTime.Now.Millisecond);
      

  4.   

    的确是如此,跳转到Random定义里面看了下Random的代码,原来Random还有怎么一回事~~多谢
      

  5.   

    楼上几位真的用过Random么?Random的无参构造方法就是以时间作为种子的,所以
    Random r = new Random(DateTime.Now.Millisecond);没有任何意义,画蛇添足楼主的原因是,所有的控件都同时创建,所以所有控件的timer都同时启动,然后所有的Timer的Elapsed都同时触发,然后所有的Random同时产生随机数,结果当然一样要想取到不一样的随机数必须让种子不同