Una de las cosas que me ha molestado mucho acerca de FileSystemWatcher es la forma en que dispara varios eventos para un único cambio lógico en un archivo. Sé por qué sucede, pero no quiero tener que preocuparme; solo quiero volver a analizar el archivo una vez, no entre cuatro y seis veces seguidas. Idealmente, habría un evento que solo se dispara cuando un archivo dado se hace cambiando, en lugar de cada paso en el camino.Extensiones reactivas frente a FileSystemWatcher
A lo largo de los años, he encontrado varias soluciones a este problema, con diversos grados de fealdad. Pensé que Reactive Extensions sería la mejor solución, pero hay algo que no estoy haciendo bien, y espero que alguien pueda señalar mi error.
que tienen un método de extensión:
public static IObservable<IEvent<FileSystemEventArgs>> GetChanged(this FileSystemWatcher that)
{
return Observable.FromEvent<FileSystemEventArgs>(that, "Changed");
}
En última instancia, me gustaría conseguir un evento por nombre de archivo, dentro de un determinado período de tiempo - por lo que cuatro eventos en una fila con un único nombre de archivo se reducen a una evento, pero no pierdo nada si se modifican varios archivos al mismo tiempo. BufferWithTime
suena como la solución ideal.
var bufferedChange = watcher.GetChanged()
.Select(e => e.EventArgs.FullPath)
.BufferWithTime(TimeSpan.FromSeconds(1))
.Where(e => e.Count > 0)
.Select(e => e.Distinct());
Cuando me suscribo a este observable, un solo cambio en un archivo supervisado desencadena mi método de suscripción cuatro veces seguidas, que más bien en contra del propósito. Si elimino la llamada Distinct()
, veo que cada una de las cuatro llamadas contiene dos eventos idénticos, por lo que hay algo de almacenamiento en búfer. Aumentar el TimeSpan pasado al BufferWithTime
parece no tener ningún efecto: alcancé los 20 segundos sin ningún cambio en el comportamiento.
Esta es mi primera incursión en Rx, así que probablemente me esté perdiendo algo obvio. ¿Lo estoy haciendo mal? ¿Hay un mejor enfoque? Gracias por cualquier sugerencia ...
¿Podría resumir esto en un programa completo? Me interesaría investigarlo ... –
Sí, haré un caso de prueba aislado. Ahora que lo pienso, tengo más de un observador manejando más de una carpeta, y tengo que probar que de todos modos no son cuatro observadores diferentes que reciben el mismo par de eventos. –