C# 神秘的负计数器值
我正在为项目的每个sql调用创建新线程。有数以百万计的sql调用,所以我在一个新线程中调用一个过程来处理sql调用 在这样做时,我想增加和减少一个计数器,以便知道这些线程何时完成了sql查询 令我惊讶的是,计数器的输出显示为负值。怎样?当我从0开始,在过程开始时加1,在过程结束时减1 程序中的其他任何地方都不会调用此int。。下面是代码C# 神秘的负计数器值,c#,sql,counter,C#,Sql,Counter,我正在为项目的每个sql调用创建新线程。有数以百万计的sql调用,所以我在一个新线程中调用一个过程来处理sql调用 在这样做时,我想增加和减少一个计数器,以便知道这些线程何时完成了sql查询 令我惊讶的是,计数器的输出显示为负值。怎样?当我从0开始,在过程开始时加1,在过程结束时减1 程序中的其他任何地方都不会调用此int。。下面是代码 public static int counter=0; while(!txtstream.EndOfStream) { new Thread(del
public static int counter=0;
while(!txtstream.EndOfStream)
{
new Thread(delegate()
{
processline();
}).Start();
Console.WriteLine(counter);
}
public static void processline()
{
counter++;
sql.ExecuteNonQuery();
counter--;
}
输出如下所示:
1
21
-2
-2
5
没有什么神秘的,你在使用线程,对吗
++
和-->
运算符不是线程安全的。这样做
public static void processline()
{
Interlocked.Increment(ref counter);
sql.ExecuteNonQuery();
Interlocked.Decrement(ref counter);
}
没有什么神秘的,你在使用线程,对吗
++
和-->
运算符不是线程安全的。这样做
public static void processline()
{
Interlocked.Increment(ref counter);
sql.ExecuteNonQuery();
Interlocked.Decrement(ref counter);
}
如何克服
使用Interlocked.Increment
和Interlocked.decreation
安全地更改计数器的值。
为什么会发生这种情况您将计数器作为变量,它在多个线程之间共享。这个变量是非易失性的,不被任何同步块包装,因此每个线程都有自己的该变量副本。所以,若两个线程试图同时更改它的值,那个么最后访问它的线程的副本将覆盖该值想象您在两个不同的线程中启动代码:
Interlocked.Increment
和Interlocked.decreation
安全地更改计数器的值。
为什么会发生这种情况您将计数器作为变量,它在多个线程之间共享。这个变量是非易失性的,不被任何同步块包装,因此每个线程都有自己的该变量副本。所以,若两个线程试图同时更改它的值,那个么最后访问它的线程的副本将覆盖该值想象您在两个不同的线程中启动代码:
这是非常基本的线程。两个线程可以在写入同一个值之前读取该值,那么两个加法的结果将仅为一个加法。然后,两次减法得到的总值是-1Ah,我明白了。。。谢谢你的解释。这是非常基本的线程。两个线程可以在写入同一个值之前读取该值,那么两个加法的结果将仅为一个加法。然后,两次减法得到的总值是-1Ah,我明白了。。。谢谢你的解释。