System.Collections.Concurrent tiene algunas colecciones nuevas que funcionan muy bien en entornos multiproceso. Sin embargo, son un poco limitados. O bloquean hasta que un artículo esté disponible o devuelven default(T)
(métodos TryXXX).¿Colección concurrente sin bloqueo?
Necesito una colección que sea segura para subprocesos, pero en lugar de bloquear la cadena de llamada usa una devolución de llamada para informarme que al menos hay un elemento disponible.
Mi solución actual es usar un BlockingCollection, pero usar el APM con un delegado para obtener el siguiente elemento. En otras palabras, creo un delegado en un método que Take
s de la colección, y ejecuto ese delegado usando BeginInvoke
.
Desafortunadamente, tengo que mantener un montón de estado dentro de mi clase para lograr esto. Peor aún, la clase no es segura para subprocesos; solo puede ser usado por un solo hilo. Estoy bordeando el mantenimiento, que preferiría no hacer.
Sé que hay algunas bibliotecas que hacen que lo que estoy haciendo aquí sea bastante simple (creo que el Marco reactivo es uno de estos), pero me gustaría lograr mis objetivos sin agregar referencias fuera de la versión 4 del marco.
¿Hay algún patrón mejor que pueda usar que no requiera referencias externas que logren mi objetivo?
tl; dr:
¿Hay patrones que satisfacen el requisito:
"Tengo que señalar una colección que estoy listo para el siguiente elemento, y tener la colección ejecutar una devolución de llamada cuando llega el siguiente elemento, sin ningún hilo bloqueado ".
¿Esto será seguro para subprocesos? ¿Qué impide que el elemento disponible deje de estar disponible antes de invocar al delegado? ¿Y cuál es su objetivo general (es decir, un sistema de colas)? –
@Adam Buen punto para consumir el artículo. El delegado toma el elemento eliminado de la colección. Por lo tanto, la ejecución del delegado se bloquea hasta que un elemento sea 'Take'-en de la colección, y ese elemento es el' objeto 'que se pasa a EndInvoke. El objetivo general es un poco intrincado; esencialmente tengo que ralentizar un flujo de trabajo hasta que el artículo esté disponible. No puede bloquear la ejecución del flujo de trabajo, por lo tanto, simplemente 'Tomar' un elemento no funcionará cuando la llamada se bloquee. Tengo que crear un marcador, luego pasarlo a una extensión. La extensión invoca al delegado, reanudando el marcador dentro de la devolución de llamada. – Will
Desafortunadamente, tengo poca experiencia con los flujos de trabajo: intente agregar ese detalle a su pregunta y podría despertar el interés de alguien :-) –