如果每个请求只需要一个数字,在 ASP.NET MVC 应用程序中生成随机数的正确方法是什么?根据 MSDN,为了获得足够质量的随机性,有必要使用单个 System.Random 对象生成多个数字,创建一次。由于在 MVC 中为每个请求创建了一个 Controller 类的新实例,因此我不能使用在 Controller 的构造函数中为 Random 对象初始化的私有(private)字段。那么我应该在 MVC 应用程序的哪个部分创建和存储 Random 对象?目前我将它存储在 Controller 类的静态字段中,并在使用它的操作方法中延迟初始化它:
public class HomeController : Controller
{
...
private static Random random;
...
public ActionResult Download()
{
...
if (random == null)
random = new Random();
...
}
}
由于 Controller 类的多个实例可以访问“随机”字段,如果两个实例尝试同时初始化它,它的值是否可能损坏?还有一个问题:我知道静态变量的生命周期就是应用程序的生命周期,但对于 MVC 应用程序,它是什么?是从 IIS 启动到 IIS 关闭吗?
最佳答案
理想情况下,您希望维护 Random
的实例。类的生命周期长于单个页面的生命周期。做 不是 通过将其放入静态变量中来做到这一点; Random
类不是线程安全的,这会导致问题。来自 the docs :
Any instance members are not guaranteed to be thread safe.
我最喜欢的方法是 RandomGen2来自 Microsoft ParallelFX 团队的包装器类(他们真的知道他们在用线程做什么),它使用每个线程的实例来处理(大部分)无锁和线程安全的随机数。
public static class RandomGen2
{
private static Random _global = new Random();
[ThreadStatic]
private static Random _local;
public static int Next()
{
Random inst = _local;
if (inst == null)
{
int seed;
lock (_global) seed = _global.Next();
_local = inst = new Random(seed);
}
return inst.Next();
}
}
然后您可以按如下方式调用:
var rand = RandomGen2.Next();
您可能需要添加额外的方法来包装其他
Random
您想要访问的方法,我建议使用更好的名称,例如 ThreadSafeRandom
,但它展示了原理。
关于asp.net-mvc - MVC 应用程序中的随机数生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2847332/