comment - param documentation c#



¿Recolección concurrente que apoya la eliminación de un artículo específico? (2)

Bastante simple: aparte de ConcurrentDictionary (que usaré si tengo que hacerlo pero no es realmente el concepto correcto), ¿existe alguna colección Concurrent (implementación de IProducerConsumer) que admita la eliminación de elementos específicos en función de la simple igualdad de un elemento o un predicado? definiendo una condición para la eliminación?

Explicación: Tengo un algoritmo de flujo de trabajo de varias etapas y múltiples subprocesos, que extrae objetos de la base de datos y los pega en una cola de "inicio". A partir de ahí, son agarrados por la siguiente etapa, se trabajan más y se rellenan en otras colas. Este proceso continúa a través de unas cuantas etapas más. Mientras tanto, la primera etapa es invocada nuevamente por su supervisor y extrae objetos de la base de datos, y pueden incluir objetos aún en proceso (porque no han terminado de procesarse y, por lo tanto, no se han vuelto a persistir con el indicador de conjunto de marcas). están terminados).

La solución que estoy diseñando es una colección maestra "en obra"; los objetos entran en esa cola cuando se recuperan para su procesamiento en la primera etapa, y se eliminan después de que se hayan vuelto a guardar en la base de datos como "procesados" en cualquier etapa del flujo de trabajo que haya completado el procesamiento necesario. Mientras el objeto esté en esa lista, se ignorará si la primera etapa lo recupera.

Había planeado usar un ConcurrentBag, pero el único método de eliminación (TryTake) elimina un elemento arbitrario de la bolsa, no uno específico (y ConcurrentBag es lento en .NET 4). ConcurrentQueue y ConcurrentStack tampoco permiten la eliminación de un elemento que no sea el siguiente que le proporcionará, dejando ConcurrentDictionary, que funcionaría pero es más de lo que necesito (todo lo que necesito es almacenar la identificación de los registros que se procesan; no cambian durante el flujo de trabajo).

https://ffff65535.com


Como ya se explicó en otras publicaciones, no es posible eliminar elementos de una Queue o ConcurrentQueue de forma predeterminada, pero en realidad la forma más fácil de moverse es extender o ajustar el elemento.

public class QueueItem
{
    public Boolean IsRemoved { get; private set; }
    public void Remove() { IsRemoved = true; }
}

Y cuando encolado:

QueueItem item = _Queue.Dequeue(); // Or TryDequeue if you use a concurrent dictionary
if (!item.IsRemoved)
{
    // Do work here
}

Es realmente difícil hacer una colección segura para subprocesos en el sentido genérico. Hay tantos factores que entran en la seguridad de subprocesos que están fuera de la responsabilidad o el alcance de una clase de biblioteca / marco que afecta la capacidad para que sea realmente "seguro para subprocesos" ... Uno de los inconvenientes que ha señalado fuera es el rendimiento. Es imposible escribir una colección performante que también sea segura para subprocesos porque tiene que asumir lo peor ...

La práctica generalmente recomendada es utilizar la colección que desee y acceder a ella de forma segura para subprocesos. Esto es básicamente el motivo por el que no hay más colecciones seguras para subprocesos en el marco. Puede encontrar más información sobre esto en http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396399.aspx#9534371





concurrent-collections