public void Test() { Assert.IsFalse(fp.GetDirectoryContents("/nonexisting").Exists); Assert.IsTrue(fp.GetDirectoryContents("/tmp").Exists); Assert.IsTrue(fp.GetDirectoryContents("/tmp/dir").Exists); Assert.IsTrue(fp.GetDirectoryContents("c:").Exists); Assert.IsFalse(fp.GetDirectoryContents("/tmp/helloworld.txt").Exists); Assert.IsTrue(fp.GetFileInfo("/tmp/helloworld.txt").Exists); Assert.IsFalse(fp.GetFileInfo("/tmp").Exists); // Read file using (Stream s = fp.GetFileInfo("/tmp/helloworld.txt").CreateReadStream()) { byte[] data = new byte[100]; int c = s.Read(data, 0, 100); Assert.AreEqual(c, HelloWorld.Length); for (int i = 0; i < c; i++) { Assert.AreEqual(data[i], HelloWorld[i]); } } // Observe IChangeToken token = fp.Watch("/tmp/**"); Semaphore semaphore = new Semaphore(0, int.MaxValue); IDisposable disposable = token.RegisterChangeCallback(o => semaphore.Release(), null); // Test, not activated Assert.IsFalse(semaphore.WaitOne(300)); Assert.IsFalse(token.HasChanged); // Test, not activated ram.CreateFile("/not-monited-path.txt"); Assert.IsFalse(semaphore.WaitOne(300)); Assert.IsFalse(token.HasChanged); // Test, not activated disposable.Dispose(); ram.CreateFile("/tmp/monited-path.txt"); Assert.IsFalse(semaphore.WaitOne(300)); Assert.IsTrue(token.HasChanged); // Observe again token = fp.Watch("/tmp/**"); semaphore = new Semaphore(0, int.MaxValue); disposable = token.RegisterChangeCallback(o => semaphore.Release(), null); ram.CreateFile("/tmp/monited-path-again.txt"); Assert.IsTrue(semaphore.WaitOne(300)); Assert.IsTrue(token.HasChanged); // Shouldn't activate any more ram.CreateFile("/tmp/monited-path-again-one-more-time.txt"); Assert.IsFalse(semaphore.WaitOne(300)); }
public void UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink_TargetDeleted(bool useWildcard) { // Arrange using var rootOfFile = new DisposableFileSystem(); string filePath = Path.Combine(rootOfFile.RootPath, Path.GetRandomFileName()); File.WriteAllText(filePath, "v1.1"); using var rootOfLink = new DisposableFileSystem(); string linkName = Path.GetRandomFileName(); string linkPath = Path.Combine(rootOfLink.RootPath, linkName); File.CreateSymbolicLink(linkPath, filePath); string filter = useWildcard ? "*" : linkName; using var provider = new PhysicalFileProvider(rootOfLink.RootPath) { UsePollingFileWatcher = true, UseActivePolling = true }; IChangeToken token = provider.Watch(filter); var tcs = new TaskCompletionSource(); token.RegisterChangeCallback(_ => { tcs.TrySetResult(); }, null); // Act File.Delete(linkPath); // Assert Assert.True(tcs.Task.Wait(TimeSpan.FromSeconds(30)), $"Change event was not raised - current time: {DateTime.UtcNow:O}, file LastWriteTimeUtc: {File.GetLastWriteTimeUtc(filePath):O}."); }
public async Task UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink(bool useWildcard) { // Arrange using var rootOfFile = new DisposableFileSystem(); string filePath = Path.Combine(rootOfFile.RootPath, Path.GetRandomFileName()); File.WriteAllText(filePath, "v1.1"); using var rootOfLink = new DisposableFileSystem(); string linkName = Path.GetRandomFileName(); string linkPath = Path.Combine(rootOfLink.RootPath, linkName); File.CreateSymbolicLink(linkPath, filePath); using var provider = new PhysicalFileProvider(rootOfLink.RootPath) { UsePollingFileWatcher = true, UseActivePolling = true }; IChangeToken token = provider.Watch(useWildcard ? "*" : linkName); var tcs = new TaskCompletionSource(); token.RegisterChangeCallback(_ => { tcs.TrySetResult(); }, null); // Act await Task.Delay(1000); // Wait a second before writing again, see https://github.com/dotnet/runtime/issues/55951. File.WriteAllText(filePath, "v1.2"); // Assert Assert.True(tcs.Task.Wait(TimeSpan.FromSeconds(30)), $"Change event was not raised - current time: {DateTime.UtcNow:O}, file LastWriteTimeUtc: {File.GetLastWriteTimeUtc(filePath):O}."); }
void Watch() { IChangeToken t = _root.GetReloadToken(); t.ActiveChangeCallbacks.Should().BeTrue(); t.RegisterChangeCallback(SetChange, null); }
public async Task UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink_TargetNotExists(bool useWildcard) { // Arrange using var rootOfLink = new TempDirectory(GetTestFilePath()); string linkName = GetTestFileName(); string linkPath = Path.Combine(rootOfLink.Path, linkName); File.CreateSymbolicLink(linkPath, "not-existent-file"); // Act using var provider = new PhysicalFileProvider(rootOfLink.Path) { UsePollingFileWatcher = true, UseActivePolling = true }; IChangeToken token = provider.Watch(useWildcard ? "*" : linkName); var tcs = new TaskCompletionSource(); token.RegisterChangeCallback(_ => { Assert.True(false, "Change event was raised when it was not expected."); }, null); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); cts.Token.Register(() => tcs.TrySetCanceled()); await Assert.ThrowsAsync <TaskCanceledException>(() => tcs.Task); }
/// <summary> /// Create observer for one file. /// </summary> /// <param name="filesystem"></param> /// <param name="patternInfo"></param> /// <param name="observer"></param> /// <param name="state"></param> /// <param name="eventDispatcher"></param> public PatternObserver(IFileSystem filesystem, GlobPatternInfo patternInfo, IObserver <IEvent> observer, object state, IEventDispatcher eventDispatcher = default) : base(filesystem, patternInfo.Pattern, observer, state, eventDispatcher) { this.changeToken = FileProvider.Watch(patternInfo.Pattern); this.previousSnapshot = ReadSnapshot(); this.watcher = changeToken.RegisterChangeCallback(OnEvent, this); }
public void PhysicalFileProvider_MoniteFile_MoniteOneTime() { var isCallBackInvoke = false; var provider = new PhysicalFileProvider(_appBasePath); IChangeToken token = provider.Watch("appsettings.json"); // 没有进行文件更改 token.RegisterChangeCallback(_ => isCallBackInvoke = true, null); Task.Delay(TimeSpan.FromSeconds(2)).Wait(); // 等待回调执行完成 Assert.False(isCallBackInvoke); Assert.False(token.HasChanged); // 进行了文件更改 var filePath = Path.Combine(provider.Root, "appsettings.json"); var fileContent = File.ReadAllText(filePath); File.WriteAllText(filePath, DateTime.Now.ToString(CultureInfo.InvariantCulture)); Task.Delay(TimeSpan.FromSeconds(2)).Wait(); // 等待回调执行完成 Assert.True(isCallBackInvoke); Assert.True(token.HasChanged); // 只能监控一次 isCallBackInvoke = false; File.WriteAllText(filePath, DateTime.Now.ToString(CultureInfo.InvariantCulture)); Task.Delay(TimeSpan.FromSeconds(2)).Wait(); // 等待回调执行完成 Assert.False(isCallBackInvoke); // !! Assert.True(token.HasChanged); File.WriteAllText(filePath, fileContent); // Token.HasChanged没有set方法, 所以只能监控一次 //token.HasChanged = false; }
public static async Task WaitForChange(this IChangeToken changeToken, int millisecondTimeout) { var tcs = new TaskCompletionSource <IChangeToken>(); IDisposable waitForChange = null; CancellationTokenSource ct = null; ct = new CancellationTokenSource(millisecondTimeout); ct.Token.Register(() => tcs.TrySetException(new TimeoutException()), useSynchronizationContext: false); waitForChange = changeToken.RegisterChangeCallback(_ => tcs.TrySetResult(changeToken), null); await tcs.Task; if (ct != null) { ct.Dispose(); ct = null; } if (waitForChange != null) { waitForChange.Dispose(); waitForChange = null; } }
private async Task BindAsync(CancellationToken cancellationToken) { await _bindSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { if (_stopping == 1) { throw new InvalidOperationException("Kestrel has already been stopped."); } IChangeToken?reloadToken = null; _serverAddresses.InternalCollection.PreventPublicMutation(); if (Options.ConfigurationLoader?.ReloadOnChange == true && (!_serverAddresses.PreferHostingUrls || _serverAddresses.InternalCollection.Count == 0)) { reloadToken = Options.ConfigurationLoader.Configuration.GetReloadToken(); } Options.ConfigurationLoader?.Load(); await AddressBinder.BindAsync(Options.ListenOptions, AddressBindContext !, cancellationToken).ConfigureAwait(false); _configChangedRegistration = reloadToken?.RegisterChangeCallback(TriggerRebind, this); } finally { _bindSemaphore.Release(); } }
/// <summary> /// Create observer for one file. /// </summary> /// <param name="filesystem"></param> /// <param name="path"></param> /// <param name="observer"></param> /// <param name="state"></param> /// <param name="eventDispatcher">(optional)</param> /// <param name="option">(optional)</param> public FileObserver(IFileSystem filesystem, string path, IObserver <IEvent> observer, object state, IEventDispatcher eventDispatcher, IOption option) : base(filesystem, path, observer, state, eventDispatcher) { this.changeToken = FileProvider.Watch(path); this.previousEntry = FileSystem.GetEntry(Filter, option); this.watcher = changeToken.RegisterChangeCallback(OnEvent, this); this.option = option; }
private void PermissionsChangedCallback(object state) { logger.LogInformation("Reloading permissions."); SendServerCommand("permission reload"); permissionsWatcher = fileProvider.Watch("permissions.json"); permissionsWatcher.RegisterChangeCallback(PermissionsChangedCallback, null); }
private void WhitelistChangedCallback(object state) { logger.LogInformation("Reloading whitelist."); SendServerCommand("whitelist reload"); whitelistWatcher = fileProvider.Watch("whitelist.json"); whitelistWatcher.RegisterChangeCallback(WhitelistChangedCallback, null); }
private void ConfigChangedCallback(object state) { using (disposibleRefHandled) { } appSettingsSection = this.configurationRoot.GetSection("AppSettings"); reloadToken = appSettingsSection.GetReloadToken(); disposibleRefHandled = reloadToken.RegisterChangeCallback(this.ConfigChangedCallback, null); settings = appSettingsSection.GetChildren().ToDictionary(x => x.Key, x => x.Value); settingsIndex = settings.Keys.ToList(); }
static void loadValues(string path) { var loadedValues = JsonConvert.DeserializeObject <Messages>(System.IO.File.ReadAllText(path)); Instance = loadedValues; token = _fileProvider.Watch("messageconfig.json"); token.RegisterChangeCallback(changeCallBack, path); }
internal static bool StartInternal(ref StartParams startParams, ref ApiFunctionPointers apiFunctionPointers, string rootDir) { if (!File.Exists(m_configFilePath)) { m_log.Log($"XPNet CLR: Will not load plugin because config file does not exist: (Path = {m_configFilePath})."); return(false); } m_config = GetConfig(m_configFilePath); if (m_config == null) { m_log.Log($"XPNet CLR: Will not load plugin because config file was unusable: (Path = {m_configFilePath})."); return(false); } m_configReloadToken = m_config.GetReloadToken(); m_configReloadTokenDisposer = m_configReloadToken.RegisterChangeCallback(o => { m_log.Log($"XPNet CLR: Config file change detected: (Path = {m_configFilePath})."); m_log.Log($"XPNet CLR: Will reconfigure logging."); m_api.Log = m_log = ReconfigureLogging(forceLogging: false); m_log.Log($"XPNet CLR: Will tell plugin that config changed."); m_api.RaiseConfigChanged(); }, state: null); // Make a local copy of the given set of API function pointers. ApiFunctions = new ApiFunctions(apiFunctionPointers); m_api = new XPlaneApi(m_log, m_config); m_plugin = LoadPlugin(rootDir); if (m_plugin == null) { m_log.Log("XPNet CLR: Failed to find a plugin to load. Will tell X-Plane we failed to start."); return(false); } var typeInfo = m_plugin.GetType().GetTypeInfo(); var xpattr = typeInfo.GetCustomAttribute <XPlanePluginAttribute>(); unsafe { fixed(byte *pc = startParams.Name) Interop.CopyCString(pc, 256, xpattr.Name); fixed(byte *pc = startParams.Signature) Interop.CopyCString(pc, 256, xpattr.Signature); fixed(byte *pc = startParams.Description) Interop.CopyCString(pc, 256, xpattr.Description); } return(true); }
private static async Task MainAsync() { IChangeToken token = _fileProvider.Watch("*.txt"); var tcs = new TaskCompletionSource <object>(); token.RegisterChangeCallback(state => ((TaskCompletionSource <object>)state).TrySetResult(null), tcs); await tcs.Task.ConfigureAwait(false); System.Console.WriteLine("quotes.txt changed"); }
// Note: we can't use DataSourceDependantCache here because we also need to handle a list of change // tokens, which is a complication most of our code doesn't have. private void Initialize() { lock (_lock) { _changeToken = new CompositeChangeToken(_dataSources.Select(d => d.ChangeToken).ToArray()); _endpoints = _dataSources.SelectMany(d => d.Endpoints).ToArray(); _changeToken.RegisterChangeCallback((state) => Initialize(), null); } }
private void RegisterChangeTokenCallback(IChangeToken token) { if (token is null) { return; } IDisposable registraton = token.RegisterChangeCallback(s => ((ChangeTokenRegistration <TState>)s).OnChangeTokenFired(), this); SetDisposable(registraton); }
/// <summary> /// Create observer for one file. /// </summary> /// <param name="assetSource"></param> /// <param name="fileProvider"></param> /// <param name="observer"></param> /// <param name="filePath"></param> public FileProviderObserver(IAssetSource assetSource, IFileProvider fileProvider, IObserver <IAssetSourceEvent> observer, string filePath) { this.assetSource = assetSource ?? throw new ArgumentNullException(nameof(assetSource)); this.observer = observer ?? throw new ArgumentNullException(nameof(observer)); this.FilePath = filePath ?? throw new ArgumentNullException(nameof(filePath)); this.fileProvider = fileProvider ?? throw new ArgumentNullException(nameof(fileProvider)); existed = fileProvider.GetFileInfo(filePath).Exists ? 1 : 0; IChangeToken changeToken = fileProvider.Watch(filePath); watcher = changeToken.RegisterChangeCallback(OnEvent, this); }
public async Task UsePollingFileWatcher_UseActivePolling_HasChanged_SymbolicLink_TargetChanged(bool useWildcard, bool linkWasBroken) { // Arrange using var rootOfFile = new DisposableFileSystem(); // Create file 2 first as we want to verify that the change is reported regardless of the timestamp being older. string file2Path = Path.Combine(rootOfFile.RootPath, Path.GetRandomFileName()); File.WriteAllText(file2Path, "v2.1"); string file1Path = Path.Combine(rootOfFile.RootPath, Path.GetRandomFileName()); if (!linkWasBroken) { await Task.Delay(1000); // Wait a second before writing again, see https://github.com/dotnet/runtime/issues/55951. File.WriteAllText(file1Path, "v1.1"); } using var rootOfLink = new DisposableFileSystem(); string linkName = Path.GetRandomFileName(); string linkPath = Path.Combine(rootOfLink.RootPath, linkName); File.CreateSymbolicLink(linkPath, file1Path); string filter = useWildcard ? "*" : linkName; using var provider = new PhysicalFileProvider(rootOfLink.RootPath) { UsePollingFileWatcher = true, UseActivePolling = true }; IChangeToken token = provider.Watch(filter); var tcs = new TaskCompletionSource <bool>(); token.RegisterChangeCallback(_ => { tcs.TrySetResult(true); }, null); var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30)); cts.Token.Register(() => tcs.TrySetCanceled()); // Act - Change link target to file 2. File.Delete(linkPath); try { File.CreateSymbolicLink(linkPath, file2Path); // Assert - It should report the change regardless of the timestamp being older. Assert.True(await tcs.Task, $"Change event was not raised - current time: {DateTime.UtcNow:O}, file1 LastWriteTimeUtc: {File.GetLastWriteTimeUtc(file1Path):O}, file2 LastWriteTime: {File.GetLastWriteTimeUtc(file2Path):O}."); } // https://github.com/dotnet/runtime/issues/56810 catch (UnauthorizedAccessException) { } }
public static void Load() { var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json", false, true) .AddJsonFile("appsettings.env.json", true, true); Config = builder.Build(); Token = Config.GetReloadToken(); Token.RegisterChangeCallback(OnChange, null); OnLoad?.Invoke(); }
private static async Task MainAsync() { var fileProvider = new PhysicalFileProvider(Directory.GetCurrentDirectory()); IChangeToken token = fileProvider.Watch(_fileFilter); var tcs = new TaskCompletionSource <object>(); token.RegisterChangeCallback(state => ((TaskCompletionSource <object>)state).TrySetResult(null), tcs); await tcs.Task.ConfigureAwait(false); Console.WriteLine("file changed"); }
static void Main(string[] args) { var builder = new ConfigurationBuilder(); builder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); //builder.AddJsonFile("appsettings.Development.json"); //builder.AddJsonFile("appsettings.ini"); var configurationRoot = builder.Build(); var config = new Config() { Key1 = "config key1", Key5 = false }; configurationRoot.GetSection("OrderService").Bind(config, binderOptions => { binderOptions.BindNonPublicProperties = true; }); Console.WriteLine($"Key1:{config.Key1}"); Console.WriteLine($"Key5:{config.Key5}"); Console.WriteLine($"Key6:{config.Key6}"); //监控配置文件变更 IChangeToken token = configurationRoot.GetReloadToken(); token.RegisterChangeCallback(state => { Console.WriteLine($"Key1:{configurationRoot["Key1"]}"); Console.WriteLine($"Key2:{configurationRoot["Key2"]}"); Console.WriteLine($"Key3:{configurationRoot["Key3"]}"); }, configurationRoot); ChangeToken.OnChange(() => configurationRoot.GetReloadToken(), () => { Console.WriteLine($"Key1:{configurationRoot["Key1"]}"); Console.WriteLine($"Key2:{configurationRoot["Key2"]}"); Console.WriteLine($"Key3:{configurationRoot["Key3"]}"); }); Console.WriteLine("开始了"); Console.ReadKey(); //Console.WriteLine($"Key1:{configurationRoot["Key1"]}"); //Console.WriteLine($"Key2:{configurationRoot["Key2"]}"); //Console.WriteLine($"Key3:{configurationRoot["Key3"]}"); Console.ReadKey(); }
private void ResetChangeSourceCore() { if (_changeTokenReleaser != null) { _changeTokenReleaser.Dispose(); _changeTokenReleaser = null; } if (_changeTokenFactory != null) { IChangeToken changeToken = _changeTokenFactory(); _changeTokenReleaser = changeToken.RegisterChangeCallback(OnChanged, null); } }
public MarkdownProvider(string repository) { this.path = Path.Combine(repository, "content"); this.source = new PhysicalFileProvider(path, ExclusionFilters.Sensitive); converter = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); changes = source.Watch("*.md"); changes.RegisterChangeCallback(o => OnSourceChanged(), changes); header = source.GetFileInfo("header.html"); footer = source.GetFileInfo("footer.html"); lock (renderedPages) { renderDirectory(new DirectoryInfo(path)).GetAwaiter().GetResult(); } }
private void PropertiesChangedCallback(object state) { logger.LogInformation("Server properties changed, triggering server restart."); if (CurrentPlayerCount() != 0) { SendServerCountdown("Server restart in {0}.", 30, 20, 10, 5, 3, 2, 1); } SendServerMessage("Restarting server now."); StopServer(); StartServer(); propertiesWatcher = fileProvider.Watch("server.properties"); propertiesWatcher.RegisterChangeCallback(PropertiesChangedCallback, null); }
private IChangeToken InitFileWatcher(string directoryPath) { string pattern = directoryPath + "/**/*"; this._logger.LogDebug($"Initialize watcher for directory {pattern}"); IChangeToken watcher = this._hostingEnvironment.WebRootFileProvider.Watch(pattern); if (!watcher.ActiveChangeCallbacks) { this._logger.LogWarning("File watcher does not support active callbacks. File lookup cache refresh not supported."); return(watcher); } watcher.RegisterChangeCallback(_ => this.OnFileDirectoryChanged(), null); return(null); }
internal void AttachTokens(CacheEntry cacheEntry) { if (_expirationTokens != null) { lock (this) { for (int i = 0; i < _expirationTokens.Count; i++) { IChangeToken expirationToken = _expirationTokens[i]; if (expirationToken.ActiveChangeCallbacks) { _expirationTokenRegistrations ??= new List <IDisposable>(1); IDisposable registration = expirationToken.RegisterChangeCallback(ExpirationCallback, cacheEntry); _expirationTokenRegistrations.Add(registration); } } } } }
public void Test1() { Debug.WriteLine("开始监测文件夹"); string rootPath = Directory.GetCurrentDirectory(); var phyFileProvider = new PhysicalFileProvider(rootPath); IChangeToken changeToken = phyFileProvider.Watch("*.json"); changeToken.RegisterChangeCallback(_ => { CallBack(); }, "xiaoming"); Console.ReadLine(); /* * 只能触发一次 */ }
private static void WatchForFileChanges() { IEnumerable <string> files = Directory.EnumerateFiles(_filePath, "*.*", SearchOption.AllDirectories); foreach (string file in files) { if (_files.TryGetValue(file, out DateTime existingTime)) { _files.TryUpdate(file, File.GetLastWriteTime(file), existingTime); } else { if (File.Exists(file)) { _files.TryAdd(file, File.GetLastWriteTime(file)); } } } _fileChangeToken = _fileProvider.Watch("**/*.*"); _fileChangeToken.RegisterChangeCallback(Notify, default); }