首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只有在设置断点时才创建唯一键,否则将复制密钥。

只有在设置断点时才创建唯一键,否则将复制密钥。
EN

Stack Overflow用户
提问于 2015-11-09 21:04:28
回答 1查看 30关注 0票数 1

因此,我确信对此有一个简单的解释,但我使用C#已经几个月了,所以我还有很多需要学习的地方。

我只是在开发一个小应用程序,它能生成一组独特的按键,只是一些基本技能的积累。

在这个问题上,如果我通过所有迭代在keyList.Add(sb.ToString());和F5设置一个断点,就会得到一个键列表,并且所有键都有唯一的值,但是如果我移除断点并只运行解决方案,它只会重复相同的键。

有人能解释一下为什么会发生这种事吗?这与Random()或我放置的StreamWriter有关吗?

代码语言:javascript
复制
public class KeyCreator
{
    public static void alphaList()
    {
        string lowerAlpha = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
        string upperAlpha = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
        SortedList<string, string> alphaList = new SortedList<string, string>();
        string[] splitListLower = lowerAlpha.Split(',');
        string[] splitListUpper = upperAlpha.Split(',');
        for (int i = 0; i < splitListLower.Length; i++)
        {
            alphaList.Add(splitListLower[i], splitListUpper[i]);
        }
        numberGen(alphaList);
    }

    public static void numberGen(SortedList<string, string> alphaList)
    {
        List<string> keyList = new List<string>();
        for (int b = 0; b < 20; b++)
        {
            int max = alphaList.Count;
            StringBuilder sb = new StringBuilder();
            Random rnd = new Random();
            for (int i = 0; i < 4; i++)
            {
                int upperLower = rnd.Next(0, 10);
                if (upperLower < 5)
                {
                    for (int a = 0; a < 4; a++)
                    {
                        int lowerUpper = rnd.Next(0, 10);
                        if (lowerUpper < 4)
                        {
                            int index = rnd.Next(0, max);
                            sb.Append(alphaList.Keys[index]);
                        }
                        else if (lowerUpper > 3 && lowerUpper < 7)
                        {
                            int index = rnd.Next(0, max);
                            sb.Append(alphaList.Values[index]);
                        }
                        else if (lowerUpper > 6)
                        {
                            int rand = rnd.Next(0, 9);
                            sb.Append(rand);
                        }
                    }
                }
                else if (upperLower > 4)
                {
                    for (int a = 0; a < 4; a++)
                    {
                        int lowerUpper = rnd.Next(0, 10);
                        if (lowerUpper < 4)
                        {
                            int index = rnd.Next(0, max);
                            sb.Append(alphaList.Keys[index]);
                        }
                        else if (lowerUpper > 3 && lowerUpper < 7)
                        {
                            int index = rnd.Next(0, max);
                            sb.Append(alphaList.Values[index]);
                        }
                        else if (lowerUpper > 6)
                        {
                            int rand = rnd.Next(0, 9);
                            sb.Append(rand);
                        }
                    }
                }
                if (i < 3)
                {
                    sb.Append("-");
                }
            }
            keyList.Add(sb.ToString());
        }
        using (StreamWriter writer = new StreamWriter(@"C:\temp\keys.txt"))
        {
            foreach (string key in keyList)
            {
                writer.WriteLine(key);
            }
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-09 21:09:27

问题是:

代码语言:javascript
复制
public static void numberGen(SortedList<string, string> alphaList)
{
    List<string> keyList = new List<string>();
    for (int b = 0; b < 20; b++)
    {
        int max = alphaList.Count;
        StringBuilder sb = new StringBuilder();
        Random rnd = new Random();   //<-- This line is the problem

默认情况下,Random是以当前日期/时间为种子的。由于DateTime的准确性并不是很好,所以您正在一次又一次地创建相同的随机数。当您中断调试器时,它会工作,因为您暂停的时间足够长,使DateTime能够进行足够的更改,从而为Random创建一个新的种子。

解决办法是这样做:

代码语言:javascript
复制
[ThreadStatic]
static Random rnd = new Random();
public static void numberGen(SortedList<string, string> alphaList)
{
    //This if is required because it can be null on subsequent threads.
    if (rnd == null) rnd = new Random();
    List<string> keyList = new List<string>();
    for (int b = 0; b < 20; b++)
    {
        int max = alphaList.Count;
        StringBuilder sb = new StringBuilder();

将创建移动到循环之外,并使用相同的实例。

此外,正如Scott在评论中所指出的,Random不应该是线程安全的静态方法,所以我添加了[[ThreadStatic]属性](https://msdn.microsoft.com/en-us/library/system.threadstaticattribute(v=vs.110%29.aspx),以避免在每个Next调用周围需要lock。不这样做并从多个线程调用它会导致Random状态损坏并返回所有零。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33618241

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档