unicos una repetir repetidos quitar lista identificar encontrar eliminar elementos datos array c# queue filesystemwatcher no-duplicates

c# - repetir - ¿Cómo eliminar elementos duplicados de una cola dentro de un marco de tiempo?



no repetir elementos en python (4)

¿Por qué no simplemente rechazar insertos si tienen rutas duplicadas? Todo lo que tiene que hacer es una búsqueda lineal comenzando desde el final de la cola y detenerse cuando encuentra un duplicado (y rechaza el inserto) o cuando la marca de tiempo excede su límite de tiempo (e inserta el registro)? Parece mucho más simple que mantener otra estructura de datos y toda la lógica asociada.

Me gustaría eliminar entradas duplicadas de una cola de una manera eficiente. La cola tiene una clase personalizada con DateTime y FullPath y algunas otras cosas

private Queue<MyCustomClass> SharedQueue;

DateTime en la clase es la marca de tiempo cuando se inserta en la cola. La lógica que me gustaría utilizar es la siguiente: eliminar duplicados de la cola si FullPath es idéntico en una ventana de 4 segundos (es decir, si se agrega a la cola dentro de los 4 segundos de una ruta completa duplicada). Tengo los eventos que quiero ver, pero aún llegarán algunos duplicados y eso está bien.

Estoy usando c # 2.0 y la clase FileSystemWatcher y una cola de trabajo.

Hay varias maneras de hacerlo: recorte la cola cada vez que se le agrega un elemento, o cuando estoy trabajando en la cola, omita el procesamiento del elemento duplicado actual.

¿O debería usar una variable ''global private'' Dictionary <String, DateTime>? ¿Entonces puedo buscarlo rápidamente? o una copia local de la cola? ¿Quizás es mejor limitar la cola local a 100 elementos en el caso de muchos eventos de archivos? Aunque en mi caso ''debería'' ser solo un número relativamente pequeño de archivos en una carpeta ... pero las cosas siempre cambian ...

Gracias por cualquier ayuda.

: Edit: Feb 10 8:54 EST: Así que decidí implementar una buena solución simple hasta donde yo sé. No creo que me aferre demasiado a las teclas Dict ...

: Edit: Feb 10 9:53 EST: Actualizado como mi diccionario no puede contener valores duplicados.

public void QueueInput(HotSynchUnit.RcdFSWFile rcd) // start the worker thread when program starts. // call Terminate.Set() in the programs exit routine or close handler etc. { // lock shared queue lock (SharedQueue) { if (!IsDuplicateQueueInput(rcd)) // only add unique values to queue { SharedQueue.Enqueue(rcd); SomethingToDo.Set(); } } } // public void QueueInput private bool IsDuplicateQueueInput(HotSynchUnit.RcdFSWFile rcd) /* Return true if the object is a duplicate object. * Pseudo Code: * * isDuplicate = false * Lock Dictionary * -If lastTimeStamp > 4 seconds ago then // Optimization: save lastTimeStamp * if Dict.Count > 0 then clear Dictionary * return isDuplicate * -If not Dict.TryGetValue(sPath, dtTimeStamp) then * Dict.AddKey() * -Else * Compare key timestamp to Currenttime * if key timestamp is <= 4 seconds ago then * IsDuplicate = True * * Dict.RemoveKey() * Dict.AddKey() * * return isDuplicate */ { // put real code here }


Haría una clase contenedora y no extendería desde la cola, ya que los usuarios del tipo base Cola esperan un comportamiento diferente. (Los contratos de datos en .NET 4.0 incluso pueden quejarse cuando lo haga).

Internamente puede tener una cola real a la que redirigir las llamadas requeridas. Cada llamada de Queue () puede agregar el nuevo elemento a un diccionario cuando ya no está contenido. Antes de hacerlo, puede vaciar todos los elementos que tengan más de x segundos de este diccionario y agregarlos a la cola interna en orden.

Al realizar la extracción, deberá comprobar si la cola interna contiene elementos y, de lo contrario, seleccionar el elemento más antiguo del diccionario.

Por supuesto, esta es solo una posible implementación. Cuando una gran cantidad de elementos diferentes pueden ponerse en cola rápidamente, el diccionario se llenará rápidamente y es posible que se deba agregar una lógica adicional para resolverlo.


Haría una subclase:

class MyDeduplicatedQueue : Queue<MyCustomObject> { /// etc }

Luego puede poner toda la lógica de filtrado apropiada en el método Enqueue .


Solo pensé en usar cualquier colección similar a una tabla genérica ... Algo como esto:

Dictionary<string, YourClass> dict = new Dictionary<string, YourClass>(); /// just let''s assume you want to add/check for "c:/demo.txt" if (!dict.ContainsKey(@"c:/demo.txt")) { /// add items to dict by passing fullPath as key and your objects as value dict.add(@"c:/demo.txt", obj1); } else if (dict[@"c:/demo.txt"].CheckForIntervall()) { /// replace current object in dictionary with new object - in case you want to.. /// or just do what you want to }

editar: su clase personalizada puede tener alguna funcionalidad como esta:

class YOURCUSTOMCLASS { private DateTime creationTime; public DateTime CreationTime { get { return creationTime; } } public YOURCUSTOMCLASS(parametersGoesHere xyz) { creationTime = DateTime.Now; } /// in this case this method will return true /// if the timeSpan between this object and otherObject /// is greater than 4 seconds public bool CheckForInterval(YOURCUSTOMCLASS otherObject) { TimeSpan diff = otherObj.CreationTime.Subtract(creationTime); /// you may replace 4 through any other digit, or even better take /// a const/global var/static ... return diff.TotalSeconds > 4; } /// all the other stuff you need ... }

Por supuesto, perderá la funcionalidad de una cola , pero obtendrá un aumento masivo en el tiempo de ejecución si su cola contiene muchos elementos.

hth