2009-10-12 3 views
0

Я пытаюсь получить случайно выбранное фоновое изображение (из 4-х изображений), чтобы оно отображалось в качестве фонового изображения для панели asp.net.Случайное фоновое изображение на DIV

Проблема заключается в том, что код работает при переходе через код в режиме отладки. После запуска кода на веб-сайте без отладки все изображения одинаковы. Его почти так, как если бы случайное число не получалось достаточно быстро.

Пользовательский контроль находится внутри информационного центра.

UserControl это:

<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

ответ

1

Иногда, случайно не совсем случайный ...

Джон Скит имеет хорошую статью по теме: Why am I getting the same numbers out of Random time and time again?

процитировать прямо, что Джон рассказал мне один раз:

Генератор псевдослучайных чисел (например, System.Random) на самом деле не случайный - он всегда будет получать то же самое последовательность результатов при инициализации с тем же дат а. Данные, которые используются для инициализации , представляют собой число , называемое семенем.

Основная проблема заключается в том, что когда вы создать новый экземпляр Random с помощью конструктора без параметров (как мы делаем здесь) он использует семя, принятое от «текущего времени». Идея компьютера из «текущего времени» может только изменить один раз в 15мс (который вечность в вычислениях) - так что если вы создаете несколько новых экземпляров Random в быстрой последовательности, они будут все имеют одинаковые семена ,

Что вы обычно хотите (если вы не заботятся о возможности воспроизводить точные результаты, и вы не нужен криптографически безопасный генератор случайных чисел ) будет иметь один случайный используемый в вашей программа, инициализируется при первом использовании. Это похоже на то, что вы можете просто использовать статическое поле где-то (выставлено как свойство ) - в основном одноэлементный. К сожалению System.Random не thread-safe - если вы называете это из двух различных тем, вы могли бы получить проблемы (включая получение одинаковых последовательность номеров в обоих потоках).

Вот почему я создал StaticRandom в моих маленьких утилит набор инструменты - это в основном потокобезопасный способ получения случайных чисел, используя один экземпляр Random и замок. См. http://www.yoda.arachsys.com/csharp/miscutil/usage/staticrandom.html для быстрого примера и http://pobox.com/~skeet/csharp/miscutil для самой библиотеки.

Разное Утилита Генератор случайных Джона Скита

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

Я думаю, что вы на что-то! страница цитирует «Если вы используете одно и то же начальное значение дважды, вы получите одну и ту же последовательность случайных чисел. Случайное использует текущее время в качестве семени. Приведенный выше код создает несколько экземпляров в очень быстрой последовательности, а« текущее время »- имеет тенденцию иметь зернистость не менее 10 мс, поэтому многие экземпляры будут иметь одно и то же семя и, таким образом, создать одну и ту же последовательность чисел ». Я считаю, что код выполняет, что быстро получает тот же самый временной код «семя», что и другие панели, и, следовательно, одно и то же изображение. Мне нужен более надежный случайный метод. –

+0

@Ian - взгляните на класс MiscUtility Jon, у которого есть генератор случайных чисел «Robust». (ссылка в сообщении). Я также отредактировал сообщение, чтобы включить его код. –

+0

@metro smurf, используя код miscutility, решил проблему. Спасибо всем за вашу помощь. –

0

Вы уверены, что ваша страница не кэшируется? Сделайте источник просмотра на странице.

О, и должна быть какая-то функция, например urand или srand, чтобы сделать случайный случай более случайным.

+0

просмотреть исходный код показывает, 4 панели, имеющие один и тот же BackgroundImage URL. Обновление страницы иногда заменяет все 4 изображения на другой набор из 4, или иногда он сохраняет то же самое. –

0

Интересно, есть ли у вас некоторый уровень кэширования на панели, что заставляет его не запускать обработку на стороне сервера в режиме производства.

+0

код на стороне сервера должен работать, поскольку изображения действительно меняются, хотя на производственной площадке он меняет все 4 изображения на панели. Запуск в режиме отладки гарантирует, что каждая панель получает свое собственное случайное изображение .... –

+0

Точно - это почти похоже на то, что панель проходит через серверную обработку в первом экземпляре, а затем использует кешированную версию элемента управления для итераций 2 - 4. Мне интересно, связано ли это с некоторыми оптимизациями режима производства. У Metro Smurf был хороший вопрос о случайном поколении - смогли ли вы устранить эту проблему? Если это так, я бы посмотрел дальше на любое кэширование .net, которое может происходить на уровне страницы или приложения –

+0

, все еще глядя в случайный код –