You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中Random快速调用返回重复值,无需Thread.Sleep如何解决?

问题原因

该现象本质就是代码运行速度过快导致的,核心和Random类的种子生成机制有关:

  • 无参构造的Random实例默认使用系统时钟的当前滴答数作为随机种子,而系统时钟的更新精度通常只有10~15ms,短时间内连续实例化多个Random时,系统时钟还未完成更新,所有实例会拿到完全相同的种子,最终生成的随机序列完全一致。
  • 加Thread.Sleep()的作用是等待系统时钟更新到下一个滴答,让每个新Random实例拿到不同种子,所以随机结果恢复正常。
  • 调试时能看到不同值是因为断点停留会产生时间间隔,相当于手动引入了延迟,和加Sleep的效果一致,全速运行时没有延迟就会出现输出全相同的问题。
替代解决方案

通用C#场景方案

全局复用同一个Random实例,避免每次调用都重新实例化即可,修改后代码如下:

class Program
{
    // 全局仅实例化一次Random
    private static readonly Random _random = new Random();
    
    static void Main(string[] args)
    {
        var mytest = new Program();
        Console.WriteLine(mytest.test());
        Console.WriteLine(mytest.test());
        Console.WriteLine(mytest.test());
    }

    public int test()
    {
        int testrandom = _random.Next(5, 100);
        return testrandom;
    }
}

如果是多线程场景使用,需要给Random的调用逻辑加锁,避免线程安全问题。

Unity场景专属方案

Unity引擎自带了更适配游戏开发的随机数工具UnityEngine.Random,不需要手动维护实例,直接调用对应API即可:

  • 生成随机数直接用Random.Range(min, max),底层由引擎统一维护随机种子,不会出现短时间调用结果重复的问题。
  • 生成随机位置的示例代码:
// 示例:生成范围自定义的三维随机坐标
Vector3 randomPos = new Vector3(
    Random.Range(0f, 10f),
    Random.Range(0f, 5f),
    Random.Range(0f, 20f)
);
// 在随机位置生成目标预制体
Instantiate(targetPrefab, randomPos, Quaternion.identity);

如果需要固定随机序列方便问题复现,只需要在游戏初始化时设置一次Random.InitState(自定义种子数值)即可,不需要每次生成随机数都重复设置。


内容的提问来源于stack exchange,提问作者ezgameworkplace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 02:09:02