简体   繁体   English

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

[英]c# while loop runs extra time

Trying to make program run on list of urls and open limited number of threads to process them. 试图让程序在URL列表上运行并打开有限数量的线程来处理它们。 Problem is that the while loop will execute when listPosition is 18, even that the siteUrls.Count is 18. But it will never show any of those test messageboxes i added. 问题是当listPosition为18时,while循环将执行,即使siteUrls.Count为18.但它永远不会显示我添加的任何测试消息框。 Thread code itself has a locker that does currentThreads-- in the end of thread's work. 线程代码本身有一个在线程工作结束时执行currentThreads的锁定器。

Why does it start the while loop when the condition becomes (18<18)? 当条件变为(18 <18)时,为什么它会启动while循环? Why does it try to launch thread with the 18 but it wont show a message box? 为什么它尝试使用18启动线程但它不会显示消息框? Problem exists only when i put more threads than list items count. 只有当我输入的线程多于列表项数量时才存在问题。 Its strange to me because i think it should not run the loop when listPosition equals _siteUrls.Count. 它对我来说很奇怪,因为我认为当listPosition等于_siteUrls.Count时它不​​应该运行循环。 I tried adding various "waiting" for threads to start and what not, but it still doesn't work. 我尝试添加各种“等待”线程启动和不启动,但它仍然无法正常工作。

ps when i add 5ms wait before increasing listPosition it becomes more stable. ps当我在增加listPosition之前添加5ms等待它变得更稳定。 What exactly does it need to wait for so i can program it in more nicely? 它究竟需要等待什么才能更好地编程呢?

pps Thread doesn't operate any of the counters except doing lock (ThreadsMinus) { currentThreads--;} pps除了执行锁定(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++;
    }

Your code manipulates counters ( listPosition and currentThreads ) in unsafe way. 您的代码以不安全的方式操作计数器( listPositioncurrentThreads )。 Please use Interlocked.Increment and Interlocked.Decrement or appropriate lock around access to each counter. 请使用Interlocked.IncrementInterlocked.Decrement或适当lock每个计数器的访问权限。

Also it is unclear from the sample where currentThreads is decreased (as pointed out by Mike Parkhill), which is the most likely reason of infinite loop. 此外,从样本中还不清楚currentThreads减少了(正如Mike Parkhill所指出的),这是无限循环的最可能原因。

Try the following (note you need to lock currentTheads in here too): 请尝试以下操作(注意您还需要在此处锁定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++;
      } 
    }

}

It will only spark off a new thread if you're under the maxThreads, but because not every iteration will start a thread you could iterate multiple times for any given listPosition until a thread becomes available. 如果你在maxThreads下,它只会引发一个新线程,但是因为不是每个迭代都会启动一个线程,你可以为任何给定的listPosition迭代多次,直到一个线程可用。 So even though you only have 18 urls in your list you could iterate over that while loop a thousand times before they've all been serviced depending on how long your Register method takes. 因此,即使您的列表中只有18个URL,您也可以在它们全部服务之前循环一次,这取决于您的Register方法需要多长时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM