1

试图让程序在 url 列表上运行并打开有限数量的线程来处理它们。问题是当 listPosition 为 18 时,while 循环将执行,即使 siteUrls.Count 为 18。但它永远不会显示我添加的任何测试消息框。线程代码本身有一个执行 currentThreads 的储物柜——在线程工作结束时。

为什么当条件变为(18<18)时它会启动while循环?为什么它尝试使用 18 启动线程但它不会显示消息框?仅当我放置的线程数超过列表项数时才会出现问题。这对我来说很奇怪,因为我认为当 listPosition 等于 _siteUrls.Count 时它不应该运行循环。我尝试添加各种“等待”线程启动,但它仍然不起作用。

ps 当我在增加 listPosition 之前添加 5ms 等待它变得更加稳定。它究竟需要等待什么,以便我可以更好地对其进行编程?

pps 线程不操作任何计数器,除了做 lock (ThreadsMinus) { currentThreads--;}

  listPosition = 0;

    while (listPosition < siteUrls.Count)
    {
        if (listPosition == 18)
        {
            MessageBox.Show("18");
        }
        currentThreads++;
        var t = new Thread(() => Register(siteUrls[listPosition], listPosition));
        t.Start();

        if (listPosition == 18)
        {
            MessageBox.Show("18");
        }
        while (currentThreads >= maxThreads)
        {
            Thread.Sleep(50);
        }
         listPosition++;
    }
4

2 回答 2

2

您的代码以不安全的方式操作计数器 (listPositioncurrentThreads)。请使用Interlocked.IncrementInterlocked.Decrement/或适当lock访问每个柜台。

此外,从样本中也不清楚在哪里currentThreads减少(正如 Mike Parkhill 所指出的),这是无限循环的最可能原因。

于 2012-12-11T03:11:07.517 回答
1

尝试以下操作(请注意,您也需要在此处锁定 currentTheads):

while (listPosition < siteUrls.Count)
{


    lock(ThreadsMinus){
      // only start a new thread if we haven't hit the maximum yet, otherwise keep spinning
      if (currentThreads < maxThreads){
         currentThreads++;
         var t = new Thread(() => Register(siteUrls[listPosition], listPosition));
          t.Start();
          listPosition++;
      } 
    }

}

如果您在 maxThreads 下,它只会触发一个新线程,但因为并非每次迭代都会启动一个线程,您可以对任何给定的 listPosition 进行多次迭代,直到一个线程可用。因此,即使您的列表中只有 18 个 url,您也可以迭代该 while 循环一千次,然后根据您的 Register 方法需要多长时间,它们都得到服务。

于 2012-12-11T03:09:59.357 回答