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

Tal*_*ode 87 c# static multithreading

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

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

Mar*_*ell 88

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

共享状态的示例是:

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

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

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

  • @prabhakaran如果一个文件句柄是一个方法变量,它只限**那个调用者.任何其他调用者都将使用不同的*变量*(方法变量是每次调用).现在,访问**底层文件**是一个单独的问题,但这与c#或.NET无关.如果句柄未共享,那么如果可能出现这种情况,可能会出现某种互斥/锁定. (8认同)

Guf*_*ffa 24

是的,这只是运气.;)

如果方法是静态的并不重要,重要的是数据是否是静态的.

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

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

  • 喜欢这一行 - "如果方法是静态的,那么无关紧要,重要的是数据是否是静态的".只是要添加,在静态方法范围内声明的局部变量不会形成我们需要在给定场景中烦恼的那部分数据. (6认同)

Dou*_*son 14

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

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

  • 这里的关键字是同步:-) (2认同)
  • 可以同时进行阅读,但是同时进行读写会导致意外的行为 (2认同)

Mar*_*ote 7

MSDN总是说:

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

编辑:正如这里的人说的那样并非总是如此,显然这适用于在BCL中以这种方式设计的类,而不适用于不适用的用户创建的类.

  • 唷!最后,我理解了本说明在MSDN文档中经常出现的含义.所以基本上,当MS在BCL中设计静态方法(发布本说明)时,它们不会访问任何超出该方法范围的变量/成员/状态.它们完全依赖于方法范围的局部变量来实现该方法的逻辑.很高兴你分享了. (2认同)