线程奇怪的地方?

时间:2011-05-26 01:10:23

标签: c# asp.net multithreading

我正在维护一些现有页面并遇到System.Threading的一些代码,我不知道该怎么做。

(这是它的要点)

protected void Page_Load(object sender, EventArgs e)
{
    XmlDocument xmlDoc = GetFromCMS();
    var nodes = xmlDoc.SelectNodes("/xpath/to/nodes");

    int i = 0;
    while (i < nodes.Count)
    {
        //do stuff with nodes[i]

        //last line in while loop - this is where I'm confused
        Math.Max(System.Threading.Interlocked.Increment(ref i), i - 1);
    }
}

做这样的事情有意义吗?取而代之的是i无法增加i++吗?我不熟悉多线程,但鉴于此页面上没有没有其他线程代码并且没有真正“特殊”发生(没有创建额外的线程等),它似乎有点奇怪我

感谢您的协助!

3 个答案:

答案 0 :(得分:7)

你的直觉是正确的 - 代码 有点奇怪,可能会很好地提交给The DailyWTF

我不确定原始开发人员的动机,但没有任何其他上下文,该方法似乎是线程安全的。您应该可以使用i增加i++;而无风险。

更好的是,您可以通过重写为i而取消foreach

protected void Page_Load(object sender, EventArgs e)
{
    XmlDocument xmlDoc = GetFromCMS();
    var nodes = xmlDoc.SelectNodes("/xpath/to/nodes");

    foreach(var node in nodes)
    {
        //do stuff with node
    }
}

答案 1 :(得分:4)

i是一个局部变量(不与任何其他线程共享),因此简单的i++是安全的。

所以,替换这个:

Math.Max(System.Threading.Interlocked.Increment(ref i), i - 1);

用这个

i++;

或者作为评论者指出,请使用简单的forforeach循环替换!

答案 2 :(得分:1)

除非您以某种方式与其他线程共享本地i变量(非常值得怀疑),i++也可以正常工作,而不会产生互锁增量函数的开销。

我能看到发生这种情况的唯一方法是,如果你在循环体内通过引用将i传递给另一个函数,然后再共享它。如果它只是在本地使用,你就可以了。