(entero) La documentación de la propiedad position
en una corriente dice:cómo hacer frente a la posición en la aC# corriente
- Cuando se reemplaza en una clase derivada, obtiene o establece la posición dentro de la corriente corriente.
- La propiedad Position no realiza un seguimiento del número de bytes de la secuencia que se han consumido, omitido o ambos.
Eso es todo. OK, así que estamos bastante claros en lo que no nos dice, pero realmente me gustaría saber de qué se trata realmente . ¿Cuál es 'la posición' para? ¿Por qué querríamos alterarlo o leerlo? Si lo cambiamos, ¿qué ocurre?
En un ejemplo práctico, tengo un flujo que periódicamente se escribe, y tengo un hilo que intenta leer de él (lo ideal es lo antes posible). Después de leer muchos problemas de SO, reinicié el campo position
en cero para comenzar mi lectura. Una vez hecho esto:
- ¿Esto afecta a dónde el escritor de esta secuencia intentará poner los datos? ¿Necesito hacer un seguimiento de la última posición de escritura? (es decir, si configuro la posición en cero para leer, ¿el escritor comienza a sobrescribir todo desde el primer byte?)
- En caso afirmativo, ¿necesito un semáforo/bloqueo alrededor de este campo de "posición" (¿subclases, quizás?) debido a mis dos hilos accediendo a ella?
- Si no gestiono esta propiedad, ¿el autor simplemente desborda el búfer?
Quizás no entiendo el Stream en sí mismo. Lo considero como un tubo FIFO: introducir datos en un extremo y extraerlos en el otro. Si es no como este, entonces ¿tengo que seguir copiando los datos más allá de mi última lectura (es decir, desde la posición 0x84 activada) hasta el inicio de mi memoria intermedia?
Intenté seriamente investigar todo esto por bastante tiempo, pero soy nuevo en .NET. Tal vez los Streams tienen una historia larga, orgullosa (indocumentada) que todos los demás comprenden implícitamente. Pero para un principiante, es como leer el manual de su automóvil y enterarse:
El pedal del acelerador afecta el volumen de combustible y aire enviado a los inyectores de combustible. No afecta el volumen del sistema de entretenimiento ni la presión de aire en ninguno de los neumáticos, si corresponde.
técnicamente cierto, pero en serio, lo que queremos saber es que si puré al suelo que vaya más rápido ..
EDIT - Bigger Picture
tengo datos ya sea desde un puerto serie, un socket o un archivo, y tienen un hilo que se encuentra allí esperando nuevos datos, y escribiéndolo en una o más secuencias, todas idénticas.
Una de estas transmisiones puedo acceder desde una sesión de telnet desde otra PC, y todo funciona bien.
El problema que estoy teniendo ahora es analizar los datos en el código en el mismo programa (en otra de las secuencias duplicadas). Estoy duplicando los datos en un MemoryStream, y tengo un hilo para sentarme y descifrar los datos, y volver a pasarlos a la IU. Este hilo hace un dataStream.BeginRead()
en su propio búfer, que devuelve cierta (?) Cantidad de datos hasta, pero no más que, el argumento count
. Después de tratar con todo lo que obtuve del BeginRead
, copio los datos restantes (desde el final de mi punto de lectura hasta el final de la secuencia) al inicio de mi memoria intermedia para que no se desborde.
En este punto, dado que tanto la escritura como la lectura son asíncronas, no sé si puedo cambiar la posición (ya que es un 'cursor' - gracias Jon). Incluso si envía un mensaje al otro hilo para decir que acabo de leer 28 bytes, o lo que sea, no sabrá que 28 bytes eran, y no sabrá cómo restablecer su cursor/position
. No he subclasificado ningún flujo: acabo de crear un MemoryStream y lo pasé al hilo que duplica los datos a los flujos necesarios.
Todo esto siente demasiado compleja para ser la forma correcta de hacerlo - sólo soy incapaz de encontrar un ejemplo sencillo que pueda modificar según sea necesario ..
¿Cómo, si no las personas a lidiar con un largo término de flujo de datos esporádicos que debe enviarse a alguna otra tarea que no sea instantánea para realizar?
EDIT: Solución probable
Al tratar de escribir una envoltura de secuencia alrededor de una cola, debido a la información en las respuestas, me topé this mensaje por Stephen Toub.
Ha escrito un BlockingStream
, y explica:
mayoría de los arroyos en el .NET Framework no es seguro para subprocesos, lo que significa que múltiples hilos no pueden acceder con seguridad a una instancia de la corriente al mismo tiempo y la mayoría de los flujos de mantener un único posición en la que ocurrirá la siguiente lectura o escritura. BlockingStream, por otro lado, es seguro para subprocesos y, en cierto sentido, mantiene implícitamente dos posiciones, aunque ninguna de ellas se expone como un valor numérico para el usuario del tipo. BlockingStream funciona manteniendo una cola interna de búferes de datos escritos en ella. Cuando los datos se escriben en la secuencia, el búfer escrito se pone en cola. Cuando se leen los datos de la transmisión, un búfer se elimina de la cola en una orden de primero en entrar, primero en salir (FIFO), y los datos en ella se devuelven a la persona que llama. En ese sentido, hay una posición en la secuencia en la que se producirá la siguiente escritura y una posición en la que se producirá la siguiente lectura.
Esto parece exactamente lo que estaba buscando - así que gracias por los chicos answerrs, lo único que encontraron esto desde sus respuestas.
Montones de información, aquí, gracias. Después de sus dos últimos párrafos, comencé a escribir un contenedor de flujo alrededor de una cola, pero encontré una solución en mi investigación que debería funcionar: he añadido a mi pregunta – DefenestrationDay
La documentación dice "Buscando en cualquier ubicación más allá de la longitud de la secuencia es compatible ". Esperaría que la documentación especifique qué sucede cuando buscamos más allá del final. ¿Se agrega al tamaño del archivo? Probablemente no, pero debería indicar explícitamente. – user34660