如何在多线程应用程序中正确使用随机类
我需要使用随机类在公共静态函数内的多线程应用程序中生成随机数。我怎样才能实现它。目前,下面的函数运行得很好,但与随机类相比,它不是很快。因此,我需要修改下面的函数并使其与随机类一起使用,同时该类正在发生数千个并发调用。如果我使用随机,它会为我认为的每个调用使用相同的种子,并且随机化非常糟糕。 我当前的类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
public static class GenerateRandomValue
{
static RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider();
public static int GenerateRandomValueDefault(int irRandValRange)//default min val 1
{
if (irRandValRange == 0)
irRandValRange = 1;
byte[] randomNumber = new byte[4]; // 4 bytes per Int32
Gen.GetBytes(randomNumber);
return Math.Abs(BitConverter.ToInt32(randomNumber, 0) % irRandValRange) + 1;
}
public static int GenerateRandomValueMin(int irRandValRange, int irMinValue)
{
byte[] randomNumber = new byte[4]; // 4 bytes per Int32
Gen.GetBytes(randomNumber);
return BitConverter.ToInt32(randomNumber, 0) % irRandValRange + irMinValue;
}
}
另一个函数看起来相当不错并且线程安全
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
public static class GenerateRandomValue
{
private static Random seedGenerator = new Random();
private static ThreadLocal<Random> random = new ThreadLocal<Random>(SeededRandomFactory);
private static Random SeededRandomFactory()
{
lock(seedGenerator)
return new Random(seedGenerator.Next());
}
public static int GenerateRandomValueMin(int irRandValRange, int irMinValue)
{
return random.Value.Next(irMinValue, irRandValRange);
}
}
I need to use random class to generate random numbers in a multi threaded application inside public static function. How can i achieve it. Currently the function below is working very well but it is not very fast when compared to random class. So i need to modify the function below and make it work with random class while thousands of concurrent calls are happening to that class. if i use random it uses same seed for every call i suppose and the randomization is being very bad.
my current class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
public static class GenerateRandomValue
{
static RNGCryptoServiceProvider Gen = new RNGCryptoServiceProvider();
public static int GenerateRandomValueDefault(int irRandValRange)//default min val 1
{
if (irRandValRange == 0)
irRandValRange = 1;
byte[] randomNumber = new byte[4]; // 4 bytes per Int32
Gen.GetBytes(randomNumber);
return Math.Abs(BitConverter.ToInt32(randomNumber, 0) % irRandValRange) + 1;
}
public static int GenerateRandomValueMin(int irRandValRange, int irMinValue)
{
byte[] randomNumber = new byte[4]; // 4 bytes per Int32
Gen.GetBytes(randomNumber);
return BitConverter.ToInt32(randomNumber, 0) % irRandValRange + irMinValue;
}
}
Another function which seems pretty good and thread safe
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Threading;
public static class GenerateRandomValue
{
private static Random seedGenerator = new Random();
private static ThreadLocal<Random> random = new ThreadLocal<Random>(SeededRandomFactory);
private static Random SeededRandomFactory()
{
lock(seedGenerator)
return new Random(seedGenerator.Next());
}
public static int GenerateRandomValueMin(int irRandValRange, int irMinValue)
{
return random.Value.Next(irMinValue, irRandValRange);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要的是一种更好的方法来在 ASP.NET 应用程序中开始播种,使用以下方法,随机的质量应该很好。
您有一个确实锁定的全局 RNG 实例,但是只有在生成新的会话状态时才会发生这种情况,之后会话仅使用其本地副本。您将在运行时获得非常好的性能,每人第一页加载的负载很小,因为它从全局存储中生成一个数字。
您可以修改它以满足您的需要,但它为您提供了总体思路,但它为您提供了总体思路。
根据 Henk Holterman 的建议,这里有一个无锁解决方案,可能更快并且不使用 HttpState。
What you need is a better way to start the seeding in your ASP.NET application, the quality of Random should be fine using the below method.
You have one instance of a global RNG that does lock, however this is only hit when a new session state is generated, after that the session uses only it's local copy. You will get very good performance at run time with a slight load on the first page load per person as it generates one number from the global store.
You can modify this to suit your needs but it gives you the general idea, but it gives you the general idea.
Per Henk Holterman's suggestion, here is a lock less solution that may be faster and does not use HttpState.
除了速度之外,您没有指定任何限制,所以我认为 < code>Random 应该可以。
You didn't specify any constraints other than speed, so I would think that
Random
should do.我建议使用 System.Web.Security.Membership.GeneratePassword() 方法。
I would suggest
System.Web.Security.Membership.GeneratePassword()
method.使用具有良好种子的随机应该会更好地“性能明智”。但你需要性能吗?
检查此博客的指标:http://blogs.msdn .com/b/pfxteam/archive/2009/02/19/9434171.aspx
最后有一个关于与提供商播种的提示。
不过,请持保留态度。您必须重做测试才能确定。
Using Random with a good seed is suppose to be "performance wise" better. But do you need the performance ?
Check this blog for metrics : http://blogs.msdn.com/b/pfxteam/archive/2009/02/19/9434171.aspx
There is a hint at the end about seeding with the provider.
Take it with a grain of salt though. You will have to redo the tests to be sure.