.net 是否可接受锁定(AppDomain.CurrentDomain)?

.net 是否可接受锁定(AppDomain.CurrentDomain)?,.net,synchronization,appdomain,.net,Synchronization,Appdomain,我想使用AppDomain.CurrentDomain.GetAssemblys()枚举Asp.NET应用程序中所有加载的程序集。但是,在检查AppDomain的文档时,我发现以下语句: 线程安全性 此类型的任何公共静态(在Visual Basic中共享)成员都是线程安全的。任何实例成员都不能保证线程安全 由于GetAssemblies()是一个实例方法,因此我必须对该调用进行某种锁定(如果不是其他的话),以防止其他人在我枚举当前程序集时将新程序集加载到域中。我希望AppDomain能够提供某种

我想使用
AppDomain.CurrentDomain.GetAssemblys()
枚举Asp.NET应用程序中所有加载的程序集。但是,在检查AppDomain的文档时,我发现以下语句:

线程安全性

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

由于
GetAssemblies()
是一个实例方法,因此我必须对该调用进行某种锁定(如果不是其他的话),以防止其他人在我枚举当前程序集时将新程序集加载到域中。我希望AppDomain能够提供某种类型的SyncRoot属性,但事实并非如此,而且我还没有在web上找到任何关于如何做的信息

我该如何同步这个电话

编辑

  • 我知道lock语句用于创建一个协作锁,这正是我希望以其他人所做(或应该做)的方式锁定AppDomain的原因,而不是创建我自己的锁,该锁不会阻止非我的代码在枚举程序集时加载程序集
  • 我知道任何人都可以使用锁通常是个坏主意,但我也知道在执行不安全操作时不使用锁更糟糕
  • 到目前为止,两个答案都说getAssemblys()实际上是线程安全的。这对我来说是有意义的,我真的希望如此,但你怎么知道的?有人有证据支持这一主张吗?我的GoogleFu让我失望,Reflector显示这个方法是一个内部原生方法的薄包装

  • SyncRoot属性通常是一个非常糟糕的主意。其中一个原因是,两个独立开发的库可能会在不知不觉中决定锁定共享SyncRoot属性,并在应用程序中快速引入死锁。锁定是一种无法在两个独立组件之间可靠共享的操作。这里最好的策略是开发自己的锁,组件使用它来同步访问


    在这种情况下,尽管从多个线程调用getAssembly是安全的,所以不需要锁定。您看到的警告是添加到BCL中每个类的一般语句,除非作者专门设计了线程安全类型并删除了该消息

    这是一个标准的免责声明;你不必为此担心。
    通常,只要您(或其他线程)不修改对象,就可以从多个线程调用实例方法


    请注意。

    NB:
    lock
    关键字不会“锁定对象”,因此其他代码无法使用它。相反,它保证任何其他试图获取同一对象上的锁的代码都必须等待所有其他锁(当前锁和之前锁)被释放。换句话说,“除了我,没有人使用这个”场景只有在对象只在锁块中使用时才是现实的。如果任何代码在没有获得锁的情况下使用它,那么这些语义都会失败。我确切地知道lock关键字的作用,并且我也知道您几乎不应该锁定公共对象。但是,我也知道竞争条件是最难调试的问题之一,因此我最想避免它们。此外,你永远不应该锁定你不拥有的东西。如果你没有创建AppDomain对象,你应该小心锁定它。我在哪里可以看到它是一个标准的免责声明,并且不特别关注这个方法?相反,在汇编类的文档中,您可以阅读“此类型是线程安全的”。我的问题是,我不知道是否有其他人修改了该对象,因为另一个同步请求可能(直接或间接)调用Assembly.Load,这无疑会修改已加载程序集的列表。我如何确保它是安全的?它没有被记录为方法安全,AppDomain类被记录为线程不安全。程序集类OTOH被证明是线程安全的。顺便说一句,SyncRoot不是一个坏主意。坏主意是让状态如此共享,以至于你永远不知道谁在使用它。但是,当发生这种情况时,AppDomain就是这样(有充分的理由),拥有SyncRoot比没有SyncRoot要好,因为没有定义良好的对象来锁定会使您无法防止竞争条件。