我正在编写一个Web链接检查程序,遇到无法解释的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的唯一被触摸的位置。)

    我究竟做错了什么?

    最佳答案

    我要大步走出去,建议LinkChecker触发一个以上的事件来调用Check()。缺少这一点,我看不到该值如何可能变为负数。

    关于c# - 遇到意外的链式行为?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6089225/

    10-11 21:58