C#:如果从多个线程调用静态方法怎么办?

时间:2010-06-14 13:38:48

标签: c# multithreading static

在我的应用程序中,我有一个静态方法,可以同时从多个线程调用。我的数据是否存在混淆的危险?

在我的第一次尝试中,该方法不是静态的,我正在创建该类的多个实例。在那种情况下,我的数据以某种方式混淆了。我不确定这是怎么发生的,因为它有时只会发生。我还在调试。 但是现在这个方法是静态的,到目前为止我没有问题。也许这只是运气。我不确定。

4 个答案:

答案 0 :(得分:84)

在方法中声明的变量(可能除了“捕获的”变量)被隔离,因此您不会遇到任何固有的问题;但是,如果您的静态方法访问任何共享状态,则所有投注均已关闭。

共享状态的例子是:

  • 静态字段
  • 从公共缓存(非序列化)访问的对象
  • 通过输入参数获取的数据(以及这些对象上的状态),如果多个线程可能触及同一个对象

如果您有共享状态,则必须:

  • 一旦可以共享,请注意不要改变状态(更好:使用不可变对象来表示状态,并将状态快照转换为局部变量 - 即不是反复引用whatever.SomeDatawhatever.SomeData 一次进入局部变量,然后只使用变量 - 请注意,这只会对不可变状态有所帮助!)
  • 同步对数据的访问(所有线程必须同步) - 互斥或(更细粒度)读者/作者

答案 1 :(得分:19)

是的,这只是运气。 ;)

方法是否静态无关紧要,重要的是数据是否为静态。

如果每个线程都有自己独立的类实例及其自己的数据集,则不存在数据混淆的风险。如果数据是静态的,则只有一组数据,并且所有线程共享相同的数据,因此无法将其混淆。

当您在不同实例中的数据仍然混淆时,很可能是因为数据并非真正分开。

答案 2 :(得分:12)

对于多个线程,静态方法应该没问题。

另一方面,静态数据可能会导致问题,因为需要控制从不同线程访问相同数据的尝试,以确保一次只有一个线程正在读取或写入数据。

答案 3 :(得分:7)

MSDN总是说:

  

此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的。不保证任何实例成员都是线程安全的。

修改: 正如这里所说的那样,情况并非总是如此,显然这适用于在BCL中以这种方式设计的类,而不适用于用户创建的不适用的类。