c# - 在共享相同方法的多个线程中使用 Random

标签 c# wpf multithreading dispatcher

我正在使用 xaml 创建一个简单的赛车应用

<StackPanel>
    <Slider x:Name="racerOne" Maximum="1000"/>
    <Slider x:Name="racerTwo" Maximum="1000"/>
    <Button Content="Start Race" Click="myButton_Click"/>
</StackPanel>

我使用下面的代码

    private void myButton_Click(object sender, RoutedEventArgs e)
    {
        Task firstRacer = Task.Run(() => Race(racerOne));
        Task secondRacer = Task.Run(() => Race(racerTwo));
    }

    private void Race(Slider racer)
    { 
        int step = 0;

        while (step < 1000)
        {
            step += new Random().Next(0, 10);
            Dispatcher.BeginInvoke(new ThreadStart(() => racer.Value = step));
            Thread.Sleep(new Random().Next(0, 300));
        }
    }

大多数时候(比如说 90%)两个 slider 似乎一起移动,而在调试中我可以看到每个线程为 step 生成不同的值。怎么会?

最佳答案

Random 由时钟播种;你可能想做这样的事情:

Random rand1 = new Random();
Random rand2 = new Random(rand1.Next());
Task firstRacer = Task.Run(() => Race(racerOne, rand1));
Task secondRacer = Task.Run(() => Race(racerTwo, rand2));

private void Race(Slider racer, Random rand)
{ 
    int step = 0;

    while (step < 1000)
    {
        step += rand.Next(0, 10);
        Dispatcher.BeginInvoke(new ThreadStart(() => racer.Value = step));
        Thread.Sleep(rand.Next(0, 300));
    }
}

这将创建两个单独的 Random 实例具有不同的种子(通过使用第一个来为第二个种子),然后将它们传递到 Race 作为参数。这消除了由于时间安排而导致过度预测行为的任何风险。

关于c# - 在共享相同方法的多个线程中使用 Random,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19974530/

相关文章:

multithreading - 多线程 gSOAP 服务

android - 蓝牙的线程或异步任务?

c# - 在 .NET 中动态添加引用

.net - MVVM 场景中的报表查看器 (rdcl)

wpf - (MVVM-light) style.triggers 不起作用

java - 为什么可以在循环中创建具有相同变量名的线程对象?

C# 在 winforms 上验证文本框的输入

c# - 如何在 EntityFramework Core 中使用部分类和部分 OnModelCreating 方法扩展 DbContext

c# - 集合类和 IDisposable 接口(interface)

wpf - MVVM IValueConverter Convert 方法在期望 float 时获取空字符串参数