C#随机数生成器陷入循环 [英] C# Random Number Generator getting stuck in a cycle

查看:198
本文介绍了C#随机数生成器陷入循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用.NET创建人工生命程序,并且正在使用在Singleton中定义的C#伪随机类.这个想法是,如果我在整个应用程序中使用相同的随机数生成器,则只能保存种子,然后从种子重新加载以重新计算某个有趣的运行.

I am using .NET to create an artificial life program and I am using C#'s pseudo random class defined in a Singleton. The idea is that if I use the same random number generator throughout the application, I could merely save the seed and then reload from the seed to recompute a certain interesting run.

public sealed class RandomNumberGenerator : Random
{
    private static readonly RandomNumberGenerator instance = new RandomNumberGenerator();

    RandomNumberGenerator()
    {

    }

    public static RandomNumberGenerator Instance
    {
        get
        {
            return instance;
        }
    }
}

我还想要一种可以给我两个不同随机数的方法.

I also wanted a method that could give me two different random numbers.

public static Tuple<int, int> TwoDifferentRandomNumbers(this Random rnd, int minValue, int maxValue)
    {
        if (minValue >= maxValue)
            throw new ArgumentOutOfRangeException("maxValue", "maxValue must be greater than minValue");
        if (minValue + 1 == maxValue)
            return Tuple.Create<int, int>(minValue, maxValue);

        int rnd1 = rnd.Next(minValue, maxValue);
        int rnd2 = rnd.Next(minValue, maxValue);
        while (rnd1 == rnd2)
        {                
            rnd2 = rnd.Next(minValue, maxValue);
        }
        return Tuple.Create<int, int>(rnd1, rnd2);            
    }

问题是有时rnd.Next(minValue,maxValue总是返回minValue.如果我此时断点并尝试创建一个double并将其设置为rnd.NextDouble(),它将返回0.0.有人知道为什么会这样吗?

The problem is that sometimes rnd.Next(minValue,maxValuealways returns minValue. If I breakpoint at this point and try creating a double and setting it to rnd.NextDouble(), it returns 0.0. Anyone know why this is happening?

我知道这是一个伪随机数生成器,但是坦率地说,我没想到它会锁定为0.正在从多个线程访问该随机数生成器...这可能是问题的根源吗?

I know that it is a pseudo random number generator, but frankly, I hadn't expected it to lock at 0. The random number generator is being accessed from multiple threads... could this be the source of the problem?

谢谢,问题最终出在线程安全上.

EDIT : Thanks, the problem ended up being thread safety.

这是该课程的新版本.

 public sealed class RandomNumberGenerator : Random
{
    private static Random _global = new Random();
    [ThreadStatic]
    private static Random _localInstance;

    RandomNumberGenerator()
    {

    }

    public static Random Instance
    {
        get
        {
            Random inst = _localInstance;
            if (inst == null)
            {
                int seed;
                lock (_global) seed = _global.Next();
                _localInstance = inst = new Random(seed);
            }
            return _localInstance;
        }
    }
}

推荐答案

如果即使保存种子也仅对多个线程使用一个RNG,则下次启动时将无法生成相同的数字应用程序,因为您将不确定来自不同线程的RNG调用将以相同的顺序进行.

If you use only One RNG for multiple threads even if you save the seed, you won't be able to generate the same numbers the next time you launch your application because you won't be sure that the calls to the RNG from the different threads will be in the same order.

如果您的线程数是固定的/已知的,请为每个线程创建RNG并保存每个种子.

If you have a fixed/known number of thread make a RNG per Thread and save each seed.

如果您100%确保每个线程使用相同的种子都将以与上次完全相同的顺序调用RNG,请忘记我刚才所说的话.

Forget what I just said if you're 100% sure that each thread will call the RNG with exactly the same order as the last time if you use the same seed.

这篇关于C#随机数生成器陷入循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆