1 votes

Pourquoi ma méthode d'extension html de nombres aléatoires renvoie-t-elle les mêmes valeurs ?

Nous donnons une démonstration dans quelques jours et je dois aller sur place pour maquetter un grand nombre de nos vues. Cela inclut la création d'un grand nombre de données fictives, etc. Je me suis dit que j'allais ajouter une boucle et une méthode d'extension qui renvoie des nombres aléatoires pour que je n'aie pas à créer moi-même ces données codées en dur.

Voici mon code de visualisation :

<% for(int i = 1; i < 7; i++) { %>
  <tr>
    <td class="auditsTableAgencyElement">Agency <%=i %></td>
    <td class="auditsTableResults"><%= Html.GetRandomNumber(0, 30) %></td>
    <td class="auditsTableResults"><%= Html.GetRandomNumber(0, 100) %>%</td>
    <td class="auditsTableResults"><%= Html.GetRandomNumber(0, 20) %></td>

    <% foreach (var record in Model.Categories) { %>
      <td class="auditsTableResults"><%= Html.GetRandomNumber(0, 30) %></td>
      <td class="auditsTableResults"><%= Html.GetRandomNumber(0, 100) %>%</td>
      <td class="auditsTableResults"><%= Html.GetRandomNumber(0, 20) %></td>
    <% } %>
  </tr>
<% } %>

Voici à quoi ressemble ma vue après avoir effectué cette opération : alt text

Les mêmes chiffres à l'avenir. Mes demandes de nombres aléatoires sont-elles mises en cache et me sont-elles renvoyées ? Si c'est le cas, comment puis-je désactiver cette fonctionnalité pour cette méthode uniquement ?

public static string GetRandomNumber(this HtmlHelper html, int low, int high)
{
  Random myRand = new Random();
  return myRand.Next(low, high).ToString();
}

10voto

Jon Skeet Points 692016

Comme toujours dans ce genre de cas, le problème est que vous créez une nouvelle Random à chaque itération.

Créez une instance unique et réutilisez-la à plusieurs reprises. Vous pouvez utiliser une variable statique, mais cela ne sera pas sûr pour les threads. Dans ce cas particulier, la création d'une nouvelle instance par page serait probablement acceptable. Cependant, vous obtiendrez toujours les mêmes données si deux personnes accèdent à la page en même temps.

Idéalement, vous pourriez créer un aléa statique utilisé de manière sûre pour les threads, afin de créer de nouvelles instances d'aléa qui peuvent ensuite être utilisées sans verrouillage au sein d'un seul thread. Par exemple :

public static class RandomFactory
{
    private static Random rng = new Random();
    private static readonly object padlock = new object();

    public static Random CreateRandom()
    {
        lock (padlock)
        {
            return new Random(rng.Next());
        }
    }
}

Ensuite, dans votre page, vous pourriez avoir :

// Instance variable
protected readonly Random rng = RandomFactory.CreateRandom();

et changez votre méthode en :

public static string GetRandomNumber(this HtmlHelper html, Random rng,
                                     int low, int high)
{
    return rng.Next(low, high).ToString();
}

(Je ne sais pas très bien pourquoi vous avez obtenu des HtmlHelper (pour être honnête, vous ne l'utilisez pas...)

et enfin votre marquage pour des choses comme celles-ci :

<%= Html.GetRandomNumber(rng, 0, 30) %>

1voto

Dan Atkinson Points 6043

Je vous renvoie à ici :

getRandomNumber

-P

</sarcasm>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X