【问题标题】:Random background image on DIVDIV 上的随机背景图像
【发布时间】:2009-10-12 20:27:30
【问题描述】:

我正在尝试获取随机选择的背景图片(从 4 张图片中选择)作为 asp.net 面板的背景图片。

我遇到的问题是,在调试模式下单步执行代码时,代码工作。一旦你在网站上运行代码而不进行调试,所有的图像都是一样的。就好像随机数没有足够快地被拾取一样。

用户控件位于数据列表中。

用户控件是这样的:

<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

【问题讨论】:

    标签: c# asp.net random panel datalist


    【解决方案1】:

    有时,随机并不是真正的随机......

    Jon Skeet 有一篇关于该主题的好文章:Why am I getting the same numbers out of Random time and time again?

    直接引用 Jon 曾经告诉我的话:

    一个伪随机数生成器(如 System.Random) 实际上并不是随机的 - 它总是会产生相同的 初始化时的结果序列 具有相同的数据。数据是 用于初始化的是一个数字 称为种子。

    基本问题是当你 使用创建一个新的 Random 实例 无参数构造函数(如 我们在这里做)它使用了一个种子 从“当前时间”。这 计算机的“当前时间”概念 只能每 15 毫秒更改一次(其中 是计算的永恒) - 所以如果 你创建了几个新的实例 随机快速连续,他们会 都有相同的种子。

    你通常想要的(假设你 不在乎能不能 重现准确的结果,而你不会 需要一个加密安全的随机数 数字发生器)是有一个单一的 在整个程序中随机使用, 第一次使用时初始化。 听起来你可以只使用 某处的静态场(暴露为 财产) - 基本上是一个单身人士。 不幸的是 System.Random 不是 线程安全 - 如果你从两个调用它 不同的线程,你可以得到 问题(包括得到相同的 两个线程中的数字序列)。

    这就是为什么我在 我的小实用工具箱 - 它是 基本上是一种线程安全的获取方式 随机数,使用单个 Random 的实例和一个锁。看 http://www.yoda.arachsys.com/csharp/miscutil/usage/staticrandom.html 举个简单的例子,和 http://pobox.com/~skeet/csharp/miscutil 对于图书馆本身。

    Jon Skeet 的 Misc 实用程序随机生成器

    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);
                }
            }
        }
    }
    

    【讨论】:

    • 我认为你的东西!该页面引用“如果您使用相同的种子值两次,您将获得相同的随机数序列。随机使用当前时间作为种子。上面的代码很快连续创建了几个实例,并且“当前时间”往往具有至少 10 毫秒的粒度,因此许多实例将共享相同的种子,从而创建相同的数字序列。”我相信代码执行得如此之快,它获得了与其他面板相同的时间代码“种子”,因此获得了相同的图像。我需要一种更稳健的随机方法。
    • @Ian - 看看 Jon 的 MiscUtility 类,它有一个“鲁棒”随机生成器。 (帖子中的链接)。我还编辑了帖子以包含他的代码。
    • @metro smurf,使用错误代码解决了这个问题。感谢大家的帮助。
    【解决方案2】:

    您确定您的页面没有被缓存吗?在页面上查看源代码。

    哦,应该有一些像 urand 或 srand 这样的函数来使随机更加随机。

    【讨论】:

    • 查看源代码显示了具有相同背景图像 url 的 4 个面板。刷新页面有时会将所有 4 张图片替换为另一组 4 张图片,或者有时保持不变。
    【解决方案3】:

    我想知道您是否在面板上运行了某种程度的缓存,导致面板无法在生产模式下通过服务器端处理运行。

    【讨论】:

    • 服务器端代码必须随着图像的变化而工作,尽管在生产站点上它会更改所有 4 个面板图像。在调试模式下运行可确保每个面板都有自己的随机图像....
    • 完全正确 - 听起来面板在第一个实例上运行服务器端处理,然后使用缓存版本的控件进行迭代 2 - 4。我想知道这是否是由于一些生产模式优化。 Metro Smurf 有一个关于随机生成的好问题——你能消除这个问题吗?如果是这样,我会进一步研究可能在页面或应用程序级别进行的任何 .net 缓存
    猜你喜欢
    • 2010-11-27
    • 2013-01-14
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    相关资源
    最近更新 更多