C#线程+锁定很奇怪

时间:2016-06-15 16:45:16

标签: c#

我的程序是一个多线程代理检查程序,每当我从我的方法返回代理IP地址并尝试回应它时,我得到了一堆,并且线程完全无意中完成。它应该为每个线程提供一行IP地址。 Here's a screenshot回应的是什么。在此之后,IP变量将返回并包含null。

我受困扰的代码(以我的名义为基础,基于一个公开的例子):

static List<String> ips = new List<String>();// this is at the start of the program class

static Random rnd = new Random();

private static String getip()
{
    if (ips.Count == 0)
    {
        return null;
    }
    return ips[rnd.Next(0, ips.Count)];
} 

此外,在while (true)循环中调用get IP,因为它是代理检查程序,我认为代码不太必要。

其他代码:

while (true)
            {
                string ip = getip();
                try
                {
                    using (var client = new ProxyClient(ip, user, pass))
                    {
                        Console.WriteLine(ip, user, pass);
                        client.Connect();
                        if (client.IsConnected)
                        {
                            return true;
                        }
                        else
                        {
                            client.Disconnect();
                            return false;
                        }
                    }
                }
                catch
                {
                    removeip(ip);
                }
                Thread.Sleep(30);
            }

例如,线程1应该有127.0.0.1(列表中的第一个IP),线程2,127.0.0.2(列表中的第二个IP)等等,此时的问题位于屏幕截图中。

编辑:这不是重复我没有解释我需要什么,Eric J的这个笔记解释了我想要做的事情,这不仅仅是随机问题。

NOTE

If you want each thread to get its own unique IP rather than a random one, you'll need to do something different than pick a random IP. You can after all get the same random IP more than once (if you flip a coin twice, you might get head twice or tails twice).

A good strategy would be to start from your List<String> ips and create one thread for each entry in that list.

1 个答案:

答案 0 :(得分:0)

我没有看到需要锁定有问题的代码。 List<T>对于读取访问是线程安全的。如果要添加或修改列表,则只需要锁定它(请参阅MSDN entry底部的“线程安全”)。

您遇到的问题与此无关。创建new Random()时,伪随机数生成器的种子基于系统时钟。快速连续的多次调用可以在相同的时钟周期内发生,这意味着它们获得相同的数字序列。

getip()之外初始化您的随机广告以避免此问题(例如,将其设为您班级的静态字段)。

static List<String> ips = new List<String>();// this is at the start of the program class

// See the discussion in comments about multithreaded access to Random()
// In particular see http://stackoverflow.com/a/19271004/141172
static Random rnd = // Get a thread safe Random instance 

private static String getip()
{
    if (ips.Count == 0)
    {
        return null;
    }
    return ips[rnd.Next(0, ips.Count)];
} 

注意

如果您希望每个线程都获得自己独特的IP而不是随机的IP,那么您需要采取与挑选随机IP不同的方法。毕竟你可以多次获得相同的随机IP(如果你掷硬币两次,你可能会得到两次或两次尾巴)。

一个好的策略是从你的List<String> ips开始,为该列表中的每个条目创建一个线程。通过应该负责的IP作为参数。