IServiceCollection.AddSingleton是否线程安全?静态扩展方法需加锁吗?
问题解答
核心结论
是否需要加锁?
默认的ServiceCollection(IServiceCollection的官方实现)内部集合操作是非线程安全的。如果你的AttachNativeLogger扩展方法会被多线程同时调用(比如并行初始化服务的场景),直接调用services.AddSingleton会有线程安全风险——比如出现重复注册、集合操作异常等问题,这种情况下必须加锁保护。如果只是在程序启动阶段单线程注册服务,就不需要额外加锁。静态类里如何实现锁?
静态类完全可以定义静态锁对象,写法和实例类类似,只需把锁对象声明为静态私有成员即可。调整后的代码示例:
public static class Extensions { // 定义全局唯一的静态锁对象 private static readonly object _loggerRegistrationLock = new object(); public static IServiceCollection AttachNativeLogger(this IServiceCollection services, ILogger logger) { ArgumentNullException.ThrowIfNull(services); var curLevel = Enum.GetValues(typeof(LogLevel)).Cast<LogLevel>().FirstOrDefault(logger.IsEnabled); var implementationInstance = new NativeLoggerForwarder(logger); implementationInstance.SetLogLevel(curLevel); lock (_loggerRegistrationLock) { services.AddSingleton(typeof(NativeLoggerForwarder), implementationInstance); } return services; } }
补充说明
微软文档未提及线程安全,是因为IServiceCollection是抽象接口,不同实现的线程安全特性可能存在差异。官方ServiceCollection的设计初衷是用于单线程启动初始化场景,如果你的使用场景超出单线程范围,就需要自行处理线程安全逻辑。
内容的提问来源于stack exchange,提问作者malat
相关产品推荐
相关产品推荐

