多用户同时访问Web.config触发文件被其他进程占用错误如何解决
故障根因与解决方案
Web.config为物理磁盘文件,多并发请求同时触发修改、保存操作时会抢占文件句柄,导致「文件正被另一进程占用」报错。你的现有代码还存在两处场景适配问题,会放大冲突概率:
- 调用了桌面程序适用的
ConfigurationManager.OpenExeConfiguration加载Web应用配置,Web场景下应使用WebConfigurationManager.OpenWebConfiguration加载站点配置 - 未做并发控制,若加密逻辑挂载在请求处理链路中,每次请求都会触发配置读写,冲突风险极高
最优修复方案
优先将加密逻辑放到应用启动入口(例如Global.asax的Application_Start事件),该事件在应用整个生命周期内仅执行一次,从根源避免并发触发问题,修正后代码如下:
// 注意引入System.Web.Configuration命名空间 var config = WebConfigurationManager.OpenWebConfiguration("~"); var section = config.GetSection(configSectionName); if (section != null && !section.SectionInformation.IsProtected) { var pcs = (ProtectedConfigurationSection)config.GetSection("configProtectedData"); var provider = pcs.DefaultProvider; section.SectionInformation.ProtectSection(provider); // 指定保存模式,仅当配置发生修改时才写磁盘,降低IO冲突 config.Save(ConfigurationSaveMode.Modified); }
运行时动态加密的兼容方案
如果业务要求必须在运行时动态触发加密,需要增加进程内锁控制,避免同一时间多个线程操作配置文件:
// 定义全局静态锁对象 private static readonly object _configLock = new object(); public void ProtectConfigSection(string configSectionName) { lock (_configLock) { var config = WebConfigurationManager.OpenWebConfiguration("~"); var section = config.GetSection(configSectionName); if (section != null && !section.SectionInformation.IsProtected) { var pcs = (ProtectedConfigurationSection)config.GetSection("configProtectedData"); var provider = pcs.DefaultProvider; section.SectionInformation.ProtectSection(provider); config.Save(ConfigurationSaveMode.Modified); } } }
额外注意事项
- 分布式部署场景不要在应用运行时执行配置加密,建议在发布流水线阶段提前完成加密操作,避免多实例同时修改配置文件的冲突
- 配置节加密依赖服务器的机器密钥,跨服务器迁移部署时需要同步对应机器密钥,否则会出现解密失败问题
内容的提问来源于stack exchange,提问作者Sagar Jena
相关产品推荐
相关产品推荐

