About this article
This article was created using an automated generation workflow powered by generative AI. Based on official Microsoft Learn documentation for FileSystemWatcher and assuming cases where a single save operation triggers multiple events, it organizes the concept of debounce—which consolidates short-term duplicate notifications—into a format that can be tested in PowerShell.Verification Status: 📘 Official specifications confirmed, actual device testing not yet performed
When using FileSystemWatcher in actual operations, you may find that "saving a file just once triggers two or three Changed events."
This is not an error; it occurs because applications often perform multiple I/O operations when saving.
What is needed in such cases isdebounce, which consolidates events arriving for the same target in a short period into a single process.
First, observe duplicate events
$dir = Join-Path $env:TEMP 'papanda-watch-debounce'
New-Item -ItemType Directory -Force $dir | Out-Null
$watcher = [System.IO.FileSystemWatcher]::new($dir)
$watcher.NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite, Size'
$watcher.EnableRaisingEvents = $true
Register-ObjectEvent -InputObject $watcher -EventName Changed -SourceIdentifier 'PapandaChanged' | Out-Null
$file = Join-Path $dir 'demo.txt'
'first' | Set-Content $file
'second' | Add-Content $file
'third' | Add-Content $file
Start-Sleep -Seconds 1
Get-Event -SourceIdentifier 'PapandaChanged' |
Select-Object TimeGenerated,
@{n='Name';e={$_.SourceEventArgs.Name}}
The number of events varies depending on the environment. The important point is thatthe number of write operations and the number of events are not necessarily one-to-one.
What is debounce?
For example, if multiple events arrive for the same demo.txt within 500 ms, this approach considers only the final event as the "target to process."
flowchart LR A[Changed #1] --> W[500ms待つ] B[Changed #2] --> W C[Changed #3] --> W W --> P[demo.txt を1回だけ処理]
The key point is not to discard the events themselves, but rather tocontrol how many times the subsequent processing is executed.
First, let's try consolidating duplicates in batches
Events are accumulated for one second and then grouped by file name.
$events = Get-Event -SourceIdentifier 'PapandaChanged'
$events |
Group-Object { $_.SourceEventArgs.FullPath } |
ForEach-Object {
$latest = $_.Group |
Sort-Object TimeGenerated -Descending |
Select-Object -First 1
[pscustomobject]@{
Path = $_.Name
EventCount = $_.Count
UseEvent = $latest.TimeGenerated
}
}
For example, even with EventCount = 3, the subsequent processing can be reduced to just a single execution.
This is a minimal conceptual version of real-time debounce. In production, you would expand it using timers or queues to "process once things have remained quiet for a certain period since the last event."
Why not simply process inside the Changed event?
For example, if you register an incoming CSV into a database for every Changed event, you risk importing the same file multiple times.
Furthermore, at the exact moment the event occurs, the other application may still be writing to the file.
Therefore, in practical scenarios, it is safer to separate the stages into:
Receiving events
Consolidating short-term events for the same file
Checking whether the file size and modification time have stabilized
Processing only once
Recording the processed state
.
Debounce alone is not enough
During heavy modifications, FileSystemWatcher's internal buffer may overflow, potentially causing events to be missed.
In other words, you need separate countermeasures for each issue:
Duplicate events → debounce
Missed events → periodic rescan
Duplicate processing → idempotency and processed state management
.
For professional use
Automatic import of CSVs arriving in shared folders
Post-processing of scanned PDFs
File integration received from external systems
Log file update monitoring
Automatic processing of build outputs
In these scenarios, it is better to design around using FileSystemWatcher as a "notification device" whileguaranteeing processing correctness through separate state management.
Cleanup
Get-Event -SourceIdentifier 'PapandaChanged' |
Remove-Event -ErrorAction SilentlyContinue
Unregister-Event -SourceIdentifier 'PapandaChanged' -ErrorAction SilentlyContinue
$watcher.Dispose()
Remove-Item $dir -Recurse -Force
Summary
FileSystemWatcher may emit multiple events for a single operation
Debounce is a concept that consolidates short-term events for the same target into a single execution
Instead of executing main processing immediately within the event Action, insert queues or state management
Countermeasures for missed events and duplicate events are different
In practice, combine idempotency, rescanning, and processed state management
