在dotnet核心中读取json文件时出错“已达到inotify实例数量的已配置用户限制(128)”

我有一个控制台应用程序(在网络核心1.1中),它每隔1分钟在cron调度程序中安排一次。 在应用程序内部有调用配置文件。 我附上下面的代码。

public static T GetAppConfig(string key, T defaultValue = default(T)) { T value = default(T); logger.Debug($"Reading App Config {key}"); try { var environmentName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"); var builder = new ConfigurationBuilder() .AddJsonFile($"appsettings.json", true, true) .AddJsonFile($"appsettings.{environmentName}.json", true, true) .AddEnvironmentVariables(); var configuration = builder.Build(); T setting = (T)Convert.ChangeType(configuration[key], typeof(T)); value = setting; if (setting == null) value = defaultValue; } catch (Exception ex) { logger.Warn(ex, $"An exception occured reading app key {key} default value {defaultValue} applied."); value = defaultValue; } return value; } 

在运行应用程序一段时间之后,此错误将在我的日志文件中获得“已达到inotify实例数量的已配置用户限制(128)”。 请找到完整的堆栈跟踪。

发生exception读取应用程序密钥DeviceId应用的默认值。
 System.IO.IOException:已达到已配置的inotify实例数的用户限制(128)。
   在System.IO.FileSystemWatcher.StartRaisingEvents()
   在System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed()
   在Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.CreateFileChangeToken(String filter)
   在Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer,Action changeTokenConsumer)
   在Microsoft.Extensions.Configuration.Json.JsonConfigurationSource.Build(IConfigurationBuilder builder)
   在Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
    at app.Shared.Utilities.GetAppConfig [T](String key,T defaultValue)in /var/app/source/app/app.Shared/Utilities.cs:line 33
   在System.IO.FileSystemWatcher.StartRaisingEvents()
   在System.IO.FileSystemWatcher.StartRaisingEventsIfNotDisposed()
   在Microsoft.Extensions.FileProviders.Physical.PhysicalFilesWatcher.CreateFileChangeToken(String filter)
   在Microsoft.Extensions.Primitives.ChangeToken.OnChange(Func`1 changeTokenProducer,Action changeTokenConsumer)
   在Microsoft.Extensions.Configuration.Json.JsonConfigurationSource.Build(IConfigurationBuilder builder)
   在Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
    at app.Shared.Utilities.GetAppConfig [T](String key,T defaultValue)in /var/app/source/app/app.Shared/Utilities.cs:line 33

请告诉我这段代码有什么问题。

 var builder = new ConfigurationBuilder() .AddJsonFile($"appsettings.json", true, true); 

每次访问设置时,您都在创建文件监视器。 第三个参数是reloadOnChange

你必须确保,

 var configuration = builder.Build() 

只在您的应用程序中调用一次并将其存储在您可以访问它的位置(最好是AVOID静态字段)。

或者只是禁用文件观察器。

  var builder = new ConfigurationBuilder() .AddJsonFile($"appsettings.json", true, false); 

或清洁:

 var builder = new ConfigurationBuilder() .AddJsonFile($"appsettings.json", optional: true, reloadOnChange: false); 

最好的方法是在接口后面抽象帽子并使用dependency injection。

 public interface IConfigurationManager { T GetAppConfig(string key, T defaultValue = default(T)); } public class ConfigurationManager : IConfigurationManager { private readonly IConfigurationRoot config; public ConfigurationManager(IConfigurationRoot config) => this.config ?? throw new ArgumentNullException(nameof(config)); public T GetAppConfig(string key, T defaultValue = default(T)) { T setting = (T)Convert.ChangeType(configuration[key], typeof(T)); value = setting; if (setting == null) value = defaultValue; } } 

然后实例化并注册它

 services.AddSingleton(new ConfigurationManager(this.Configuration)); 

并通过构造函数将其注入您的服务

看起来配置将在文件更改时自动重新加载。 因此,您应该只在应用程序启动时构建一次配置,然后从中读取。