C#线程递增一个高于预期的整数

时间:2015-07-10 10:21:00

标签: c# multithreading

首先,我想为我的程序道歉只做一半,但我想在继续该程序之前尝试解决问题。

到目前为止,我的整个解决方案如下:

WindowManager

这是我正在制作的蒙太奇计划。我将主图片的每个像素rgb与缩略图列表的平均rgb进行比较。平均rgb的缩略图接近像素rgb用于替换像素。

我已经知道会对我的节目提出很多批评。我知道最终图片的分辨率将会很大。

我想要帮助的唯一问题是为什么button1_Click函数中的整数k增加到值50,当线程中检查少于50并且for循环k不应该变为50.这个问题是什么当我接受线程并且随机发生时,不会发生这种情况。当程序中断时,整数i的值会变化(因为k被赋值为50)。这就是为什么我不能使用断点或单步执行我的程序。因为这种情况是随机发生的,当时已经创建了很多线程。

感谢您提供任何帮助。

1 个答案:

答案 0 :(得分:1)

问题是由于C#闭包本身捕获变量,其值。这与在C#5.0之前的for循环变量的作用域结合起来意味着在单个线程上运行的代码看到的k的值将随着主线程上的循环遍历其值而改变,并且最重要的是,您可以在if (k < 50)检查和k的后续使用之间进行更改。 MSDN描述了C#5.0 here中的更改。

如果你在恰当的时刻发现它,k的值可以从50增加到51,因为最后一次迭代的for循环只是之后 { {1}}在 if语句正文之前检查

由于同样的问题,您可能还会发现某些if (k < 50)的值会被跳过,而有些则会被不同的线程多次处理。

要解决此问题,您需要将k分配给本地变量并将其捕获。由于变量k是循环迭代的局部变量,因此捕获的值不会在线程内发生变化:

localK

值得补充的是,实际上保证以线程方式运行这将大大降低性能,在2500个线程之间创建和切换的开销将远远超过并行处理可能带来的任何好处。