0

asp.netパネルの背景画像として表示されるように、ランダムに選択された背景画像(4つの画像の選択から)を取得しようとしています。

私が抱えている問題は、デバッグ モードでコードをステップ実行するときにコードが機能することです。デバッグせずに Web サイトでコードを実行すると、すべての画像が同じになります。乱数が十分に迅速に取得されていないかのようです。

ユーザーコントロールはデータリスト内にあります。

ユーザーコントロールは次のとおりです。

<asp:Panel ID="productPanel" CssClass="ProductItem" runat="server">

<div class="title" visible="false">
    <asp:HyperLink ID="hlProduct" runat="server" />
</div>
<div class="picture">
    <asp:HyperLink ID="hlImageLink" runat="server" />
</div>
<div class="description" visible="false">
    <asp:Literal runat="server" ID="lShortDescription"></asp:Literal>
</div>
<div class="addInfo" visible="false">
    <div class="prices">
        <asp:Label ID="lblOldPrice" runat="server" CssClass="oldproductPrice" />
        <br />
        <asp:Label ID="lblPrice" runat="server" CssClass="productPrice" /></div>
    <div class="buttons">
        <asp:Button runat="server" ID="btnProductDetails" OnCommand="btnProductDetails_Click"
            Text="Details" ValidationGroup="ProductDetails" CommandArgument='<%# Eval("ProductID") %>'
            SkinID="ProductGridProductDetailButton" /><br />
        <asp:Button runat="server" ID="btnAddToCart" OnCommand="btnAddToCart_Click" Text="Add to cart"
            ValidationGroup="ProductDetails" CommandArgument='<%# Eval("ProductID") %>' SkinID="ProductGridAddToCartButton" />
    </div>
</div>

背後にあるコードは次のとおりです。

protected void Page_Load(object sender, EventArgs e)
    {

            // Some code here to generate a random number between 0 & 3
            System.Random RandNum = new System.Random();
            int myInt = RandNum.Next(4);

            if (productPanel.BackImageUrl != null)
            {
                switch (myInt)
                {
                    case 0:
                        productPanel.BackImageUrl = "../App_Themes/emmaharris/images/frame1.gif";
                        break;
                    case 1:
                        productPanel.BackImageUrl = "../App_Themes/emmaharris/images/frame2.gif";
                        break;
                    case 2:
                        productPanel.BackImageUrl = "../App_Themes/emmaharris/images/frame3.gif";
                        break;
                    case 3:
                        productPanel.BackImageUrl = "../App_Themes/emmaharris/images/frame4.gif";
                        break;
                }

            }
           // End of new code to switch background images

    }

T

4

3 に答える 3

1

時々、ランダムは本当にランダムではありません...

Jon Skeetには、このトピックに関する優れた記事があります。ランダムから同じ数値を何度も取得するのはなぜですか。

ジョンが一度私に言ったことを直接引用するには:

疑似乱数ジェネレーター(System.Randomなど)は実際にはランダムではありません。同じデータで初期化すると、常に同じシーケンスの結果が生成されます。初期化に使用されるデータは、シードと呼ばれる番号です。

基本的な問題は、パラメーターなしのコンストラクターを使用してRandomの新しいインスタンスを作成するときに(ここで行っているように)、「現在の時刻」から取得したシードを使用することです。コンピューターの「現在の時刻」の概念は、15ミリ秒ごとに1回だけ変更される可能性があります(これはコンピューティングの永遠です)。したがって、ランダムの新しいインスタンスをすばやく連続して作成すると、それらはすべて同じシードになります。

通常必要なのは(正確な結果を再現できることを気にせず、暗号的に安全な乱数ジェネレーターが必要ない場合)、プログラム全体で単一の乱数を使用し、最初に使用するときに初期化することです。これは、静的フィールドをどこか(プロパティとして公開)で使用できるように思えます。基本的にはシングルトンです。残念ながら、System.Randomはスレッドセーフではありません。2つの異なるスレッドから呼び出すと、問題が発生する可能性があります(両方のスレッドで同じ番号のシーケンスを取得するなど)。

これが、小さなユーティリティツールボックスでStaticRandomを作成した理由です。これは、基本的に、Randomの単一インスタンスとロックを使用して乱数を取得するスレッドセーフな方法です。 簡単な例 についてはhttp://www.yoda.arachsys.com/csharp/miscutil/usage/staticrandom.htmlを 、ライブラリ自体についてはhttp://pobox.com/~skeet/csharp/miscutilを参照 してください。

JonSkeetのその他のユーティリティランダムジェネレータ

using System;

namespace MiscUtil
{
    /// <summary>
    /// Thread-safe equivalent of System.Random, using just static methods.
    /// If all you want is a source of random numbers, this is an easy class to
    /// use. If you need to specify your own seeds (eg for reproducible sequences
    /// of numbers), use System.Random.
    /// </summary>
    public static class StaticRandom
    {
        static Random random = new Random();
        static object myLock = new object();

        /// <summary>
        /// Returns a nonnegative random number. 
        /// </summary>      
        /// <returns>A 32-bit signed integer greater than or equal to zero and less than Int32.MaxValue.</returns>
        public static int Next()
        {
            lock (myLock)
            {
                return random.Next();
            }
        }

        /// <summary>
        /// Returns a nonnegative random number less than the specified maximum. 
        /// </summary>
        /// <returns>
        /// A 32-bit signed integer greater than or equal to zero, and less than maxValue; 
        /// that is, the range of return values includes zero but not maxValue.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">maxValue is less than zero.</exception>
        public static int Next(int max)
        {
            lock (myLock)
            {
                return random.Next(max);
            }
        }

        /// <summary>
        /// Returns a random number within a specified range. 
        /// </summary>
        /// <param name="min">The inclusive lower bound of the random number returned. </param>
        /// <param name="max">
        /// The exclusive upper bound of the random number returned. 
        /// maxValue must be greater than or equal to minValue.
        /// </param>
        /// <returns>
        /// A 32-bit signed integer greater than or equal to minValue and less than maxValue;
        /// that is, the range of return values includes minValue but not maxValue.
        /// If minValue equals maxValue, minValue is returned.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">minValue is greater than maxValue.</exception>
        public static int Next(int min, int max)
        {
            lock (myLock)
            {
                return random.Next(min, max);
            }
        }

        /// <summary>
        /// Returns a random number between 0.0 and 1.0.
        /// </summary>
        /// <returns>A double-precision floating point number greater than or equal to 0.0, and less than 1.0.</returns>
        public static double NextDouble()
        {
            lock (myLock)
            {
                return random.NextDouble();
            }
        }

        /// <summary>
        /// Fills the elements of a specified array of bytes with random numbers.
        /// </summary>
        /// <param name="buffer">An array of bytes to contain random numbers.</param>
        /// <exception cref="ArgumentNullException">buffer is a null reference (Nothing in Visual Basic).</exception>
        public static void NextBytes(byte[] buffer)
        {
            lock (myLock)
            {
                random.NextBytes(buffer);
            }
        }
    }
}
于 2009-10-12T20:40:25.623 に答える
0

ページがキャッシュされていませんか?ページでソースを表示します。

ああ、ランダムをもっとランダムにするために、urandやsrandのようないくつかの機能があるはずです。

于 2009-10-12T20:36:52.667 に答える
0

パネル上である程度のキャッシュが動作しているために、本番モードでサーバー側の処理が実行されないのではないかと思います。

于 2009-10-12T20:38:12.553 に答える