代码改变世界

跨线程操作变量的陷阱。

2012-12-08 22:05 by Tsanie, ... 阅读, ... 评论, 收藏, 编辑

说是陷阱,主要还是编写代码的时候没注意……

今天有段程序出现了一个很诡异的情况,如下:

for (int i = 0; i < max; i++)
{
	// ...
	form.BeginInvoke (new MethodInvoker (delegate
	{
		// A
		int tmp = i;
		System.Threading.Thread.Sleep (100);
	}));
}

原先预想是A处触发max次,每次值分别为0,1,2,……max-1。结果事实上是0,max-1,max-1,……max-1。

经过调试,发现form的UI线程上使用的变量i地址和循环体的i地址一致,而不是他的拷贝。(我以为值类型变量不会存在这个问题)

解决方案:复制一个备份变量供给另外线程使用。