我正在编写一个网络链接检查程序,并遇到了我无法解释的 Interlocked 行为。首先,这是代码的精简版:
public class LinkCheckProcessor
{
private long _remainingLinks;
public event EventHandler<LinksCheckedEventArgs> AllLinksChecked;
private void ProcessLinks(List<Link> links)
{
foreach (Link link in links)
{
ProcessLink(link);
}
}
private void ProcessLink(Link link)
{
var linkChecker = new LinkChecker(link);
linkChecker.LinkChecked += LinkChecked;
Interlocked.Increment(ref _remainingLinks);
#if DEBUG
System.Diagnostics.Debug.WriteLine(String.Format("LinkChecker: Checking link '{0}', remaining: {1}", link, Interlocked.Read(ref _remainingLinks)));
#endif
linkChecker.Check();
}
void LinkChecked(object sender, LinkCheckedEventArgs e)
{
var linkChecker = (LinkChecker)sender;
Interlocked.Decrement(ref _remainingLinks);
#if DEBUG
System.Diagnostics.Debug.WriteLine(String.Format("LinkChecker: Checked link '{0}', remaining: {1}", linkChecker.Link, Interlocked.Read(ref _remainingLinks)));
#endif
if (Interlocked.Read(ref _remainingLinks) == 0)
{
OnAllLinksChecked(new LinksCheckedEventArgs(this.BatchId, this.Web.Url));
}
}
}
我在调试输出中看到的是:
- LinkChecker:检查链接“http://serverfault.com”,剩余:1
- LinkChecker:已检查链接“http://superuser.com”,剩余:0
- LinkChecker:检查链接“http://stackoverflow.com”,剩余:-1
我不明白为什么(在某些代码运行中)_remainingLinks
变得消极。AllLinksChecked
这也具有导致事件过早触发的副作用。(顺便说一句,上面的代码包含唯一_remainingLinks
被触及的地方。)
我究竟做错了什么?