今天在写代码的时候,突然发现奇怪的问题,调试之后,才发现是函数闭包使用错误,踩坑了。于是记录下来。
存在闭包就等同于存在数据共享,共享数据的存在往往容易引起不预期的结果;存在共享就要警惕线程安全问题,尽量避免闭包在多线程环境的使用,应该使用更为明确函数定义。
原来的代码如下
for (int i = 0; i < slotNumber; i++)
{
_locationWafers[module][i] = new WaferInfo();
DATA.Register($"System.WaferInfo", $"{module.ToString()}.Slot{i + 1:D2}", () => GetWafer(module, i), DataAttribute.DataFlag.NonPersist);
}
这里面lamada 函数是一个闭包, 闭包执行的时候,i 值已经变化了。所以,得不到最后想要的结果。于是我改成了下面的。将i 复制成新的变量。
for (int i = 0; i < slotNumber; i++)
{
int slot= i;
_locationWafers[module][i] = new WaferInfo();
DATA.Register($"System.WaferInfo", $"{module.ToString()}.Slot{slot + 1:D2}", () => GetWafer(module, slot), DataAttribute.DataFlag.NonPersist);
}
总之,尽量少用闭包吧