首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实现IDisposable的FileSystemWatcher类

实现IDisposable的FileSystemWatcher类
EN

Stack Overflow用户
提问于 2015-03-23 15:26:40
回答 1查看 621关注 0票数 0

我有一个简单的FeatureToggle类,它使用FilesSystemWatcher来查看app.config文件。如果.config文件中有更改,它将从appSettings部分重新加载设置。我让它实现了IDisposable,但是我不能使用{}语句,因为我希望在程序运行时监视.config文件,但是我希望在进程结束时调用Dispose(),并且不能向主程序添加.config()块。怎样才能叫Dispose()。我能在这里用一个终结器吗?

FeatureToggle:

代码语言:javascript
复制
    public sealed class FeatureToggle : IDisposable
        {
            private static readonly FeatureToggle instance = new FeatureToggle();

            private static FeatureWatcher featureWatcher = new FeatureWatcher();

            private static ConcurrentDictionary<string, bool> features = new ConcurrentDictionary<string, bool>();

            private bool disposed;

            static FeatureToggle()
            {
            }

            private FeatureToggle()
            {
            }

            public static FeatureToggle Instance
            {
                get
                {
                    return instance;
                }
            }

            public void Dispose()
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }

            public bool Enabled(string featureName)
            {
                string path = this.GetAssemblyPath();
                if (featureWatcher.GetWatcher(path) == null)
                {
                    FileSystemWatcher watcher = featureWatcher.AddWatcher(path);
                    if (watcher != null)
                    {
                        watcher.Changed += this.OnChanged;
                        this.Refresh(path);
                    }
                }

                return this.Get(featureName);
            }

            private void Add(string key, bool value)
            {
                features.AddOrUpdate(key, value, (k, v) => value);
            }

            private void Dispose(bool disposing)
            {
                if (this.disposed)
                {
                    return;
                }

                if (disposing)
                {
                    featureWatcher.Dispose();
                    featureWatcher = null;
                    features = null;
                }
            }

            private bool Get(string key)
            {
                bool value;
                if (features.TryGetValue(key, out value))
                {
                    return value;
                }

                return false;
            }

            private string GetAssemblyPath()
            {
                return AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
            }

            private IEnumerable<KeyValuePair<string, bool>> LoadConfig(string path)
            {
                ExeConfigurationFileMap configMap = new ExeConfigurationFileMap { ExeConfigFilename = path };
                Configuration config = ConfigurationManager.OpenMappedExeConfiguration(
                    configMap, 
                    ConfigurationUserLevel.None);

                var settings =
                    config.AppSettings.Settings.Cast<KeyValueConfigurationElement>()
                        .Where(x => x.Key.StartsWith("FeatureToggle."))
                        .ToDictionary(o => o.Key.ToString(CultureInfo.InvariantCulture), o => Convert.ToBoolean(o.Value));

                return settings;
            }

            private void OnChanged(object source, FileSystemEventArgs e)
            {
                // app.config changed - run update
                this.Refresh(e.FullPath);
            }

            private void Refresh(string path)
            {
                foreach (var kv in this.LoadConfig(path))
                {
                    this.Add(kv.Key, kv.Value);
                }
            }
        }

FileWatcher:

代码语言:javascript
复制
  public class FeatureWatcher : IDisposable
    {
        private static ConcurrentDictionary<string, FileSystemWatcher> watchers;

        private bool disposed;

        public FeatureWatcher()
        {
            watchers = new ConcurrentDictionary<string, FileSystemWatcher>();
        }

        public FileSystemWatcher AddWatcher(string path)
        {
            if (this.GetWatcher(path) == null)
            {
                var parentPath = Path.GetDirectoryName(path);
                var watcher = new FileSystemWatcher
                                  {
                                      Path = parentPath, 
                                      NotifyFilter = NotifyFilters.LastWrite, 
                                      Filter = "*.config"
                                  };

                watchers.TryAdd(path, watcher);
                watcher.EnableRaisingEvents = true;
                return watcher;
            }

            return null;
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        public FileSystemWatcher GetWatcher(string path)
        {
            FileSystemWatcher watcher;
            if (!watchers.TryGetValue(path, out watcher))
            {
                return null;
            }

            return watcher;
        }

        protected virtual void Dispose(bool disposing)
        {
            if (this.disposed)
            {
                return;
            }

            if (disposing)
            {
                // Clean up managed resources
                if (watchers != null)
                {
                    foreach (var watcher in watchers.Values)
                    {
                        watcher.EnableRaisingEvents = false;
                        watcher.Dispose();
                    }

                    watchers = null;
                }

                this.disposed = true;
            }
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-23 16:04:46

无论您有WPF应用程序、WinForms应用程序还是服务,所有这些都有events Initialized,这是初始化类的好地方,Closed是处理类的好地方。(在控制台应用程序中,您只需将所有内容都放在try..finally中即可)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29214071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档