【问题标题】:Is Mapper.Map in AutoMapper thread-safe?AutoMapper 中的 Mapper.Map 是线程安全的吗?
【发布时间】:2012-05-25 19:53:03
【问题描述】:

我现在正在查找 AutoMapper 代码(为我正在从事的项目之一评估它),坦率地说,我很惊讶:

  • 库 API 基于单个静态访问点(Mapper 类型),因此通常它的任何方法都必须是线程安全的
  • 但我没有在代码中找到任何证据。

我能找到的只是this issue,但即使是那里的陈述似乎也不正确:如果Map 在内部不使用线程安全的数据结构,它也不能被视为线程安全的,如果我要在非并发上下文中调用CreateMap,但同时与Map 调用。

即AutoMapper 唯一可能的使用模式,例如ASP.NET MVC 应用程序是:

lock (mapperLock) {
    ... Mapper.AnyMethod(...) ...
}

显然,如果我是正确的,那将是一个巨大的缺陷。

所以我有两个问题:

  • 我说的对吗?
  • 如果是,没有此问题的 AutoMapper 的最佳替代方案是什么?

【问题讨论】:

  • 主键似乎是通过ThreadSafeList<TypeMap> _typeMaps 进行的双重检查查找;是什么让您认为它不是线程安全的?你认为具体是什么不是线程安全的?
  • TypeMap 是不可变对象吗?
  • 你告诉我! (问题也是:即使不是,它是否在任何时候都被不当更新了,除了你)。您声称它不是线程安全的;请详细说明您认为不安全的内容。请注意,通常策略(一旦构建)不会更新,因此唯一需要保护的是对策略缓存的访问,这似乎是正确完成的。
  • 现在再次查找代码。实际上,我在那里错过了ThreadSafeList 的使用。
  • 我认为这个问题是完全正确的。我们不能假设该库是线程安全的,因为我们还没有找到反对它的证据。反之亦然:除非证明并非如此,否则一切都是不安全的。我想这个库的作者需要介入。

标签: .net asp.net-mvc automapper


【解决方案1】:

这个问题可能有点过时了,只是想稍微调查一下后记录一下我的一些发现。

Mapper 是一个封装类,用于封装创建新配置,以及静态内存中的新映射器实例,所以严格来说它不是线程安全的,但你可以安全地使用它,只要你只初始化配置一次。

MapperConfiguration创建新的mapper实例,并将配置记录在自己的实例内存空间中。

TLDR;

如果您只需要初始化一次配置,请选择静态 API

如果需要多次初始化配置,又担心线程安全,请选择实例API

【讨论】:

    【解决方案2】:

    链接的issue 或多或少回答了你的问题:

    Mapper.CreateMap 不是线程安全的,以后也不会。然而, Mapper.Map 是线程安全的。 Mapper 静态类只是一个瘦的 MappingEngine 和 Configuration 对象之上的包装器。

    因此,如果您以线程安全的方式在一个中心位置进行配置,请仅使用Mapper.CreateMap

    您的评论是:

    我问这个是因为我想就地配置自动机, 即在使用之前。我计划以非并发方式配置它 上下文,即 ~ lock (mapperConfigLock) { Mapper.CreateMap()....; }, 我担心现在这还不够。

    如果您正在进行就地配置,请不要使用静态 Mapper 类。正如对 github 问题的评论建议直接使用映射引擎:

    var config = 
        new ConfigurationStore(new TypeMapFactory(), MapperRegistry.AllMappers());
    config.CreateMap<Source, Destination>();
    var engine = new MappingEngine(config);
    
    var source = new Source();
    var dest = engine.Map(source);
    

    它的代码有点多,但您可以围绕它创建自己的助手。 但是在给定的方法中,一切都是本地的,因此没有共享状态,无需担心线程安全。

    【讨论】:

    • '以线程安全方式的一个中心位置' - 我认为无论如何都需要在问题中解释这一点,因为有足够的空间可能会出现错误。
    • 这里是提到的github issue的链接。
    猜你喜欢
    • 2021-10-12
    • 2015-04-18
    • 2011-10-07
    • 2012-03-02
    • 2011-10-28
    • 2023-03-14
    • 2016-08-24
    • 2011-08-16
    • 2011-09-28
    相关资源
    最近更新 更多