c# - 如何在具有多个服务器的高流量 asp.net 应用程序中实现随机数流

标签 c# asp.net

这个问题来自这样的知识,即当 new Random() 被非常快速地调用时,它会被植入相同的值,我假设它是基于 DateTime.Now.Ticks.

假设您在最新版本的 ASP.NET、IIS、.NET 等上有一个高流量的 Web 应用程序,它实现了一个在线赌场。我认为模拟老虎机需要从单个随机数流中提取。

在高交易量的情况下,您可能会得到两台具有相同随机数生成器的老虎机,从而导致累积奖金过多。我对伪随机生成器没有完全的了解,但我的直觉是,要安全地实现在线赌场,您确实需要从只播种一次的单个生成器中提取数据。

我能想到的一个解决方案是使用单个线程的同步队列来推送数字,但我不知道如何在多站点应用程序中同步它。

对于这种情况是否有好的/标准的解决方案?

更新:我正在处理的实际场景(实际上没有机会获得足够的音量来引起问题)

我的真实情况是,我有一个流量适中的 asp.net 网站,并且要求在每个请求上显示两个用户控件之一。我使用以下代码这样做:

// Randomly display one of (FreeCreditScore1, MyFreeScoreNow1)
private void ShowCreditScoreAd()
{
    FreeCreditScore1.Visible = (new Random().Next(2) == 1);
    MyFreeScoreNow1.Visible = !FreeCreditScore1.Visible;
}

如果我通过快速连续调用上面的代码来对它进行单元测试,它会失败,我开始明白原因是 new Random() 在同一个“tick”中被调用。

就是说,我确实相信我当前的实现已经足够(随时纠正我)但我很好奇如果我真的想对其严格控制,如何解决它......

最佳答案

只是用一把锁来保护随机数生成器。除非您每秒对它进行数十万次调用,否则它已经足够快了。

public class MyRandomObject
{
    private readonly Random _rnd = new Random();

    public int Next()
    {
        lock (_rnd)
        {
            return _rnd.Next();
        }
    }
}

在您说“锁太慢”之前,请注意我是在一个旧的 2.4 GHz 四核上测试它的。当锁未被竞争时,大约需要 70 纳秒才能获得一个随机数。锁争用会降低性能,但您需要大量请求。

在 Web 应用程序中,您希望在 Application_Start 中初始化其中一个,并使该单例可用于应用程序的其余部分。

有更快的方法,但更难实现。一种方法是预先生成数百万个随机数(调用 Random.NextBytes)并将它们存储在缓冲区中。用读/写锁保护它。当剩余值的数量达到某个阈值时,线程会获取写入器锁,阻止所有其他访问,直到它重新填充缓冲区。如果您使用其他一些随机数来源,这可能是您想要的方式。例如 RNGCryptoServiceProvider.GetBytes 方法 ( http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.getbytes.aspx )。

关于c# - 如何在具有多个服务器的高流量 asp.net 应用程序中实现随机数流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14971846/

相关文章:

c# - 如何检测我的页面是否是回发的结果

c# - 反序列化大量 XML 文档时忽略空引用

c# - ASP.NET C# - 多个 MySQL 事务

c# - 使用NEST和C#进行 Elasticsearch 滚动

c# - 实现一个支持实体对象延迟加载的存储库?

c# - 将 XElement 添加到 XDocument 时出现重复元素

asp.net - 服务器生成的 PDF 未显示在某些(但不是所有)PC 的 aspx 页面上的 IFrame 中

asp.net - Azure 多个网站、子域和虚拟目录

c# - Asp.net 身份电子邮件确认 token 问题 : "Invalid Token"

JavaScript 函数