C#:如果从多个线程调用静态方法会怎么样?
在我的应用程序中我有一个静态方法,从多个线程同时被调用。 我的数据是否有任何混淆的危险?
在我的第一次尝试中,这个方法不是静态的,而是创build了这个类的多个实例。 在那种情况下,我的数据混淆了。 我不知道这是怎么发生的,因为它只是有时候发生。 我仍在debugging。 但是现在这个方法是静态的,到目前为止我没有任何问题。 也许这只是运气。 我不确定。
在方法中声明的variables(可能除了“ 捕获 ”的variables)是孤立的,所以你不会有任何固有的问题; 然而,如果你的静态方法访问任何共享状态,所有的投注都closures。
共享状态的例子是:
- 静态字段
- 从公共caching访问的对象(非序列化)
- 通过input参数获得的数据(以及这些对象上的状态),如果多个线程可能触及相同的对象,
如果你有共享状态,你必须:
- 注意不要改变状态,一旦它可以共享(更好:使用不可变的对象来表示状态,并把状态的快照变成一个局部variables – 而不是引用
whatever.SomeData
反复,你读whatever.SomeData
一次一个局部variables,然后只是使用variables – 请注意,这只有帮助不可变的状态!) - 同步对数据的访问(所有线程必须同步) – 相互排斥或(更精细)的读写器
是的,这只是运气。 ;)
如果这个方法是静态的或者没有关系,那么重要的是数据是否是静态的。
如果每个线程都有自己独立的类的实例,那么就不存在混淆数据的风险。 如果数据是静态的,那么只有一组数据,并且所有的线程共享相同的数据,所以没有办法混合起来。
当你在单独的实例中的数据仍然混淆,这很可能是因为数据不是真正独立的。
静态方法应该适用于多个线程。
另一方面,静态数据可能会导致一个问题,因为试图访问来自不同线程的相同数据需要被控制,以确保一次只有一个线程正在读取或写入数据。
MSDN总是说:
此types的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的。 任何实例成员不保证是线程安全的。
编辑:正如这里的家伙们所说的,并不总是这样,显然这适用于在BCL中以这种方式devise的类,而不适用于不适用于用户创build的类。