Ваша логика AllLinksChecked
определенно неверна, поскольку счетчик может работать 0->1
, 1->0
, 0->1
, 1->0
, 0->1
, 1->0
и, таким образом, достигать нуля несколько раз.
Но я не понимаю, как счет может стать отрицательным. Это единственные места, которые _remainingLinks
появляются в вашем коде?
Первую проблему можно решить, просто удалив инкрементный код из ProcessLink
, и ProcessLinks
инициализирует счет до links.Count
перед началом цикла:
Interlocked.Exchange(ref _remainingLinks, links.Count)`
Аргумент links
не записывается из других потоков во время работы ProcessLinks
, не так ли?