Reputation: 5137
I am trying to fully understand something that seems quite mystical at this point after an hour analysis. Please bear with the detailed explanation.
I got a function in my asp.net mvc4 application.
private string GenerateDownloadCode(int id, int organizationId)
{
const int downloadCodeMinValue = 10000000;
const int downloadCodeMaxValue = 20000000;
int number = new Random().Next(downloadCodeMinValue, downloadCodeMaxValue);
return string.Format("{0}-{1}-{2}", id, organizationId, number);
}
The function is used to generate a random number for download code. I noticed that the number
value is always equal to downloadCodeMinValue
.
I checked the MSDN and dig into the implementation of Next method in framework code which looks like:
long range = (long)maxValue-minValue;
if( range <= (long)Int32.MaxValue) {
return ((int)(Sample() * range) + minValue);
}
else {
return (int)((long)(GetSampleForLargeRange() * range) + minValue);
}
Sample() method can return a value 0.0 to 1.0 and I think in my case it is always returning 0.0 causing this method to return minValue. Ok it is a "legal value for the Random number".
I can live with that until I pick up my method and copied it into LINQPad where it is generating a random number consistently.
Q1: Why same method return expected random number in LINQPad?
I read some questions around this (very close to my problem, MVC specific but does not consider my case) that explains Random
class behavior and offer some solutions.
The above links assume the code is invoked in a close loop or shorter time period, in my case this method is called at least minute difference if not hour.
I do not have a problem with getting same number back so do not want to fix the code, inability and curiosity to understand WHY it is not working in an MVC app (each request is served in a new thread) making me reach to the experts here.
Q2: So what could be the reason the the method does not return random number in an MVC app?
Update:
Context for the method - This method is used to generate a new random long (>= 12 char) enough number for each new organization added. Hence each call is minutes delayed.
Update 2:
The method is called from a method AddOrganizationUser
that exist in a different library (business or service). The service method is invoked from controller action
public ActionResult CreateUser(OrganizationUserViewModel ouser)
{
organizationUserService.AddOrganizationUser(organizationUserDomainModel, loggedInUser.Id);
}
Upvotes: 1
Views: 793
Reputation: 1383
I think u are calling this from a multi-threaded environment? Random is not thread safe.
Here are a number of ways to implement a thread safe random. http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx
Hope this helps
EDIT: Also creating a new random for each random number is bad practice.
Upvotes: 1