2009-07-08 5 views
1

Nous donnons une démo dans quelques jours et je dois y aller et maquiller beaucoup de nos points de vue. Cela inclut de faire beaucoup de fausses données, etc. Je me suis dit que je laisserais tomber une boucle et une méthode d'extension qui retourne des nombres aléatoires, donc je n'ai pas besoin de créer moi-même ces données codées en dur.Pourquoi la méthode d'extension html du nombre aléatoire retourne-t-elle les mêmes valeurs?

Voici mon code de vue:

<% 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 ce que mon point de vue ressemble après avoir fait ceci: alt text

numéros identiques sur toute la ligne. Mes demandes de numéros aléatoires sont-elles mises en cache et me sont-elles retournées? Si oui, comment 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(); 
} 

Répondre

10

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

Créez une instance unique et réutilisez-la plusieurs fois. Vous pouvez utiliser une variable statique, mais celle-ci ne sera pas adaptée aux threads. Dans ce cas particulier, créer une nouvelle instance par page serait probablement correct. Cependant, vous obtiendrez toujours les mêmes données si deux personnes accèdent à la page en même temps.

Idéalement, vous pouvez créer un random static utilisé de manière thread-safe, pour créer de nouvelles instances de Random qui peuvent ensuite être utilisées sans être verrouillées dans 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 changer votre méthode pour:

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

(Je ne suis pas sûr de savoir pourquoi vous avez HtmlHelper à tous là, pour être honnête - vous ne l'utilisez pas ...)

et enfin votre mark-up à des choses comme ceci:

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

Ne pas avoir besoin "ce HtmlHelper html", pour ce soit une méthode d'extension? – KingNestor

+0

En outre, vous mentionnez avoir une seule instance statique n'est pas thread-safe. Pouvez-vous expliquer cela pour moi? Que pourrait-il arriver avec un tas de threads appelant potentiellement next() sur cette même instance? – KingNestor

+0

@KingNestor vous en avez besoin pour que ce soit une méthode d'extension, mais vous n'avez pas besoin de cela pour appeler une fonction statique publique. –

1

Je vous renvoie à here:

getRandomNumber

:-P

</sarcasme>

Questions connexes