我正在维护一些现有页面并遇到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++
吗?我不熟悉多线程,但鉴于此页面上没有没有其他线程代码并且没有真正“特殊”发生(没有创建额外的线程等),它似乎有点奇怪我
感谢您的协助!
答案 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++;
或者作为评论者指出,请使用简单的for
或foreach
循环替换!
答案 2 :(得分:1)
除非您以某种方式与其他线程共享本地i
变量(非常值得怀疑),i++
也可以正常工作,而不会产生互锁增量函数的开销。
我能看到发生这种情况的唯一方法是,如果你在循环体内通过引用将i
传递给另一个函数,然后再共享它。如果它只是在本地使用,你就可以了。