c#while循环运行额外的时间

时间:2012-12-11 02:49:21

标签: c# multithreading .net-3.5

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

为什么在条件变为(18 <18)时启动while循环?为什么它尝试使用18启动线程但它不会显示消息框?只有当我输入的线程多于列表项数量时才存在问题。它对我来说很奇怪,因为我认为当listPosition等于_siteUrls.Count时它不​​应该运行循环。我尝试添加各种“等待”线程启动和不启动,但它仍然无效。

P.S。当我在增加listPosition之前添加5ms等待它变得更稳定。它究竟需要等待什么才能更好地编程呢?

p.p.s除了执行锁定(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++;
    }

2 个答案:

答案 0 :(得分:2)

您的代码以不安全的方式操纵计数器(listPositioncurrentThreads)。请使用Interlocked.IncrementInterlocked.Decrement或相应的lock来访问每个计数器。

从样本中还不清楚currentThreads减少了哪些(如Mike Parkhill所指出的),这是无限循环的最可能原因。

答案 1 :(得分: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个网址,您也可以在它们全部服务之前循环一次,这取决于您的Register方法需要多长时间。