FileSystemWatcher on macOS raises no Error when FSEvents drops events: the flags arrive on the watched folder's own path, which is skipped first
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 76/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- csharp, macos
- Ambito
- backend, operating-systems
Direzione di ricerca
Leggi src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.OSX.cs, in particolare ProcessEvents nella parte relativa al salto del percorso radice e alla chiamata a ShouldRescanOccur. Riproduci il problema con l’applicazione console fornita per l’eliminazione in raffica su macOS e verifica se gli FSEvents persi attivano l’evento Error del watcher. Il lavoro è terminato quando l’evento del percorso radice che contiene i flag degli eventi persi viene segnalato come errore e un test di regressione copre questo ordine.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Description
On macOS, when more changes arrive at once than FSEvents queues, FSEvents drops events and says so with one event flagged kFSEventStreamEventFlagMustScanSubDirs | kFSEventStreamEventFlagUserDropped (0x3). That event's path is the watched folder itself.
ProcessEvents in FileSystemWatcher.OSX.cs skips every event on the watched folder's own path ("Match Windows and don't notify us about changes to the Root folder") before it calls ShouldRescanOccur. So the dropped-events flags never reach the Error event. The watcher loses changes silently, and its consumer can't tell it should rescan.
Reproduction Steps
A net10.0/net11.0 console app:
using System.Collections.Concurrent;
int count = args.Length > 0 ? int.Parse(args[0]) : 1000;
string folder = Directory.CreateTempSubdirectory("fsw-burst-").FullName;
for (int i = 0; i < count; i++)
{
File.WriteAllText(Path.Combine(folder, $"F{i}.txt"), "x");
}
Thread.Sleep(1000);
ConcurrentDictionary<string, bool> deleted = new();
int errors = 0;
using FileSystemWatcher watcher = new(folder);
watcher.Deleted += (_, e) => deleted[e.FullPath] = true;
watcher.Error += (_, e) => { Interlocked.Increment(ref errors); Console.WriteLine($"Error: {e.GetException().Message}"); };
watcher.EnableRaisingEvents = true;
Thread.Sleep(1000);
Parallel.For(0, count, i => File.Delete(Path.Combine(folder, $"F{i}.txt")));
Thread.Sleep(5000);
Console.WriteLine($"{Environment.Version}: {count} files deleted, {deleted.Count} Deleted events, {errors} Error events");
Directory.Delete(folder, true);
Output on macOS 27.0.1, Apple Silicon, three runs on each runtime:
10.0.14: 1000 files deleted, 467 Deleted events, 0 Error events
10.0.14: 1000 files deleted, 544 Deleted events, 0 Error events
10.0.14: 1000 files deleted, 488 Deleted events, 0 Error events
11.0.0: 1000 files deleted, 466 Deleted events, 0 Error events
11.0.0: 1000 files deleted, 722 Deleted events, 0 Error events
11.0.0: 1000 files deleted, 1000 Deleted events, 0 Error events
A raw FSEvents stream, created with the flags the watcher uses (FileEvents, NoDefer, WatchRoot; latency 0) and watching the same burst, got 460 events: 459 file removals and one event on the watched folder's own path with flags 0x3. The same happens with IncludeSubdirectories = true and the files in a subfolder: the flagged event is still on the watched folder's path.
Expected behavior
Either a Deleted event for every file, or an Error event saying events were lost.
Actual behavior
About half the deletions are reported, with no Error event.
Regression?
Not known.
Known Workarounds
Treat a burst of changes as possibly lossy, and list again the folders it touched.
Configuration
macOS 27.0.1 (Apple Silicon), .NET 10.0.14 and 11.0.0-rc.3.26522.148.
Other information
Calling ShouldRescanOccur before the root-path skip would fix it. #130637 changes the exception this path raises to InternalBufferOverflowException. Its test reaches the path through a mount in a subfolder, so it doesn't hit this ordering.
- Lingua principale
- C#
- Stelle
- 18.4k
- Fork
- 5.8k
- Merge medio
- 2g 16h
- PR unite (30g)
- 621
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di dotnet/runtime
-
[wasi] .NET 10: WasmEnableSIMD with AOT fails because WasiApp.targets has -msimd128 commented outApertaarea-Build-mono untriaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
area-System.ComponentModel untriaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
dotnet/runtime#136608 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
area-System.IO bug untriaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
dotnet/runtime#136599 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
[mono] Native memory leak on the first invoke of every open-instance delegate to a virtual methodApertaarea-VM-meta-mono untriaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
dotnet/runtime#136284 · 6 reazioni ·
I maintainer di solito rispondono entro 1 giorno
-
Several MemoryExtensions.LastIndexOfAnyExcept overloads incorrectly document "first occurrence"Forse già presa @ehsan-raoufi l’ha presa 6 giorni fa. Apertaarea-System.Memory untriaged
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 83/100
dotnet/runtime#136282 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di dotnet/runtime
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 67/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 76/100
GameShowLDA/AskMkiM#1075 ·
I maintainer di solito rispondono entro 1 giorno
-
kind/bug triage/untriaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
unoplatform/uno.resizetizer#414 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
I maintainer di solito rispondono entro 1 giorno