我创建了一个包含5个静态函数的CommonUtils.cs文件(因此我可以将这个.cs复制到Visual Studio中的其他项目,因为我开发了不同的C#应用程序)以及我有很多源文件。
现在,我已将项目编译为DLL。此DLL由IIS服务器作为应用程序托管。许多客户使用此dll执行某些操作,比如他们生成报告。
我被告知在这种情况下不能慷慨地使用“静态函数”并且应该应用它们,因为没有锁定,“锁定”机制,单个程序实例的多个线程或程序的多个实例,两者都可以出乎意料地表现出来这是真的吗?
答案 0 :(得分:11)
我被告知不得使用“静态功能” 慷慨地在这种背景下应该应用它们,“锁定” 机制因为没有锁定,单个实例的多个线程 程序或程序的多个实例都可以表现 不料。这是真的吗?
让我们一块一块地打破它。什么是静态类?
静态类与非静态类基本相同,但是 有一个区别:静态类无法实例化。 换句话说,您不能使用new关键字来创建变量 类类型。因为没有实例变量,所以您可以访问 使用类名本身的静态类的成员。
CLR如何处理静态类?
与所有类类型的情况一样,静态的类型信息 .NET由.NET Framework公共语言运行库(CLR)加载 当加载引用该类的程序时。该程序 无法准确指定何时加载类。 然而, 保证加载并初始化其字段 在第一个引用类之前调用的静态构造函数 您计划中的时间。静态构造函数只调用一次, 并且静态类在的生命周期内保留在内存中 程序所在的应用程序域。
为什么 可能 需要锁定?
基本上,当我们有比赛条件时需要锁定。当有人可能读取其他人可能在同一时间改变他们的数据。两个独立的线程可以访问共享资源,并且没有任何机制可以阻止这种情况。为了回答你的问题,你首先要回答另一个问题。
您的静态方法是否访问共享资源并且可能存在任何竞争条件?如果这是真的,那么你需要使用锁定。否则,不需要它。
答案 1 :(得分:9)
函数是不可变的,因此在调用函数时不需要同步。函数参数是可变的,但每次调用都有自己的本地副本。无需同步。
当多个线程处理相同的数据并且至少有一个编写器时,需要进行同步。这是关于线程之间共享的任何变量。需要注意静态变量和静态变量可以访问的任何实例变量。
答案 2 :(得分:0)
听起来你有一个类库。以下是Microsoft针对需要支持多线程的类库的指南:
如果可能,请避免同步。对于使用频繁的代码尤其如此。例如,可以调整算法以容忍竞争条件而不是消除竞争条件。不必要的同步会降低性能并导致死锁和竞争条件的可能性。
默认情况下,使静态数据(在Visual Basic中为Shared)线程安全。
默认情况下,不要使实例数据线程安全。添加锁以创建线程安全代码会降低性能,增加锁争用,并可能导致死锁发生。在常见的应用程序模型中,一次只有一个线程执行用户代码,这最大限度地减少了对线程安全的需求。因此,默认情况下,.NET Framework类库不是线程安全的。
避免提供改变静态的静态方法。在常见的服务器方案中,静态状态在请求之间共享,这意味着多个线程可以同时执行该代码。这开启了线程错误的可能性。考虑使用将数据封装到不在请求之间共享的实例的设计模式。此外,如果静态数据被同步,则改变状态的静态方法之间的调用可能导致死锁或冗余同步,从而对性能产生负面影响。
从https://msdn.microsoft.com/en-us/library/1c9txz50(v=vs.110).aspx
复制答案 3 :(得分:-1)
解释“LOCK”来自MSDN说:
lock关键字通过获取给定对象的互斥锁,执行语句,然后释放锁来将语句块标记为关键部分。
lock关键字确保一个线程不进入代码的关键部分,而另一个线程处于临界区。如果另一个线程试图输入一个锁定的代码,它将等待,阻止,直到该对象被释放
参考文献:
https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx
最好在多线程中使用LOCK而不是每次都创建静态函数。