MVC 应用程序中的随机数生成
如果每个请求只需要一个数字,那么在 ASP.NET MVC 应用程序中生成随机数的正确方法是什么?根据 MSDN,为了获得足够质量的随机性,有必要使用创建一次的单个 System.Random 对象生成多个数字。由于在 MVC 中为每个请求创建一个控制器类的新实例,因此我无法使用在控制器的构造函数中为 Random 对象初始化的私有字段。那么我应该在 MVC 应用程序的哪个部分创建和存储 Random 对象?目前,我将其存储在控制器类的静态字段中,并在使用它的操作方法中延迟初始化它:
public class HomeController : Controller
{
...
private static Random random;
...
public ActionResult Download()
{
...
if (random == null)
random = new Random();
...
}
}
由于“随机”字段可以由控制器类的多个实例访问,因此它的值是否有可能被损坏如果两个实例尝试同时初始化它?还有一个问题:我知道静态的生命周期就是应用程序的生命周期,但对于 MVC 应用程序来说它是什么?是从IIS启动到IIS关闭吗?
What is the correct way of generating random numbers in an ASP.NET MVC application if I need exactly one number per request? According to MSDN, in order to get randomness of sufficient quality, it is necessary to generate multiple numbers using a single System.Random object, created once. Since a new instance of a controller class is created for each request in MVC, I cannot use a private field initialized in the controller's constructor for the Random object. So in what part of the MVC app should I create and store the Random object? Currently I store it in a static field of the controller class and lazily initialize it in the action method that uses it:
public class HomeController : Controller
{
...
private static Random random;
...
public ActionResult Download()
{
...
if (random == null)
random = new Random();
...
}
}
Since the "random" field can be accessed by multiple instances of the controller class, is it possible for its value to become corrupted if two instances attempt to initialize it simultaneously? And one more question: I know that the lifetime of statics is the lifetime of the application, but in case of an MVC app what is it? Is it from IIS startup till IIS shutdown?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
理想情况下,您希望维护
Random
类的实例的时间比单个页面的生命周期更长。不要通过将其放入静态变量中来实现此目的;Random
类不是线程安全的,这会导致问题。来自文档:我最喜欢的方法是 Microsoft 的 RandomGen2 包装类ParallelFX 团队(他们真正知道他们在线程方面做了什么),每个线程使用一个实例(主要是)无锁和线程安全的随机数。
然后您可以按如下方式调用:
您可能需要添加额外的方法来包装您想要访问的其他
Random
方法,我建议使用更好的名称,例如ThreadSafeRandom
code>,但它演示了原理。Ideally you want to maintain an instance of the
Random
class for longer than the lifetime of a single page. Do not do this by putting it in a static variable; theRandom
class is not thread-safe and this will result in problems. From the docs:My favourite approach is the RandomGen2 wrapper class from the Microsoft ParallelFX team (who really know what they're doing with threading) which uses an instance per thread for (mostly) lock-free and thread-safe random numbers.
Which you can then just call as follows:
You may need to add extra methods to wrap the other
Random
methods you want to access, and I'd suggest a better name such asThreadSafeRandom
, but it demonstrates the principle.除非您将一些快速演示或其他东西放在一起,否则我会将这个责任放入服务或基础设施层(即,只是另一个类)中,并让它管理随机数生成器的生命周期。无论如何,管理这个问题并不是控制器的工作 - 当/如果您有另一个需要随机数的控制器时,您将不必担心它。
Unless you're throwing together some quick demo or something, I would put this responsibility into a service or infrastructure layer (ie, just another class) and let it manage the lifetime of your random number generator. It's not really the controller's job to manage this anyway - and you won't have worry about it when/if you have another controller that needs a random number.
您可以在 HomeController 中有一个静态构造函数,这样您就不必在每个方法中延迟初始化它。这几乎可以确保
Random
仅初始化一次(第一次访问时)。You could have a static contructor in
HomeController
to save you having to lazy initialize it in every method. This pretty much ensures that theRandom
only gets initialised once (the very first time it's accessed).