3

new Random()この質問は、が非常に速く呼び出されると、に基づいていると私が想定しているのと同じ値がシードされるという知識から来ていDateTime.Now.Ticksます。

オンラインカジノを実装する最新バージョンのASP.NET、IIS、.NETなどにトラフィックの多いWebアプリケーションがあるとします。シミュレートされたスロットマシンは、単一の乱数ストリームからプルする必要があると思います。

大量の状況では、同じ乱数ジェネレーターを備えた2台のスロットマシンが発生し、大きなジャックポットが多すぎる可能性があります。私は疑似ランダムジェネレーターを完全には理解していませんが、オンラインカジノを安全に実装するには、一度だけシードされた単一のジェネレーターからプルする必要があるというのが私の直感です。

私が考えることができる1つの解決策は、数値をプッシュする単一のスレッドを持つ同期キューですが、マルチサイトアプリケーション間で同期する方法がわかりません。

このシナリオに対する良い/標準的な解決策はありますか?

更新:私が取り組んでいる実際のシナリオ(問題を引き起こすのに十分なボリュームを取得する可能性は実際にはありません)

私の実際の状況では、トラフィックが適度に多いasp.net Webフォームサイトがあり、要求ごとに2つのユーザーコントロールのいずれかを表示する必要があります。私は次のコードでそうしました:

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

上記のコードを連続して呼び出すことで単体テストを行うと失敗new Random()し、同じ「ダニ」で呼び出されたことが理由であることがわかりました。

そうは言っても、現在の実装で十分だと思いますが(自由に修正してください)、本当に厳密にしたければ、どうすれば解決できるのか興味がありました...

4

2 に答える 2

2

乱数発生器をロックで保護するだけです。毎秒数十万回の呼び出しを行わない限り、十分な速度が得られます。

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

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

「ロックが遅すぎる」と言う前に、これを古い2.4GHzクアッドコアでテストしたことに注意してください。ロックが競合していない場合、乱数を取得するのに約70ナノ秒かかりました。ロックの競合はパフォーマンスを低下させる可能性がありますが、多くのリクエストが必要になります。

Webアプリでは、のいずれかを初期化しApplication_Start、そのシングルトンをアプリケーションの残りの部分で使用できるようにする必要があります。

より高速な方法がありますが、実装するのはより困難です。1つの方法は、数百万の乱数を事前に生成し(call Random.NextBytes)、それらをバッファーに格納することです。リーダー/ライターロックでそれを保護します。残りの値の数があるしきい値に達すると、スレッドはライターロックを取得し、バッファーがいっぱいになるまで他のすべてのアクセスを防ぎます。これは、他の乱数ソースを使用している場合に、おそらく行きたい方法です。たとえば、RNGCryptoServiceProvider.GetBytesメソッド(http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.getbytes.aspx)。

于 2013-02-20T04:20:26.120 に答える
0

静的Randomインスタンスを1つ作成します。暗号的に安全な4つのランダムバイトを生成してシードします。Randomそのインスタンス[ThreadLocal]を作成して、すべてのロックを解除することもできます。

BCLにそのようなものが含まれておらず、それを自動的に使用して新しいインスタンスをシードする理由はわかりません。それはとても簡単で、完璧なシードを提供し、任意の数のスレッドに完全にスケーリングします。

于 2014-10-25T14:21:27.660 に答える