尝试在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++;
}
答案 0 :(得分:2)
您的代码以不安全的方式操纵计数器(listPosition
和currentThreads
)。请使用Interlocked.Increment
和Interlocked.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方法需要多长时间。