как работать с позицией в потоке c#

(вся) документация для position свойство на потоке говорит:

  • при переопределении в производном классе возвращает или устанавливает позицию в текущем потоке.
  • свойство Position не отслеживает количество байтов из потока, которые были использованы, пропущены или оба.

вот и все. Хорошо, мы достаточно ясно понимаем, что это нам не говорит, но я действительно хотел бы знать, что это факт тут подставка для. Что такое "положение"?--18-->на? Зачем нам его переделывать или читать? Если мы изменим его - что происходит?

в практическом примере у меня есть поток, который периодически записывается, и у меня есть поток, который пытается прочитать из него (в идеале ASAP). От чтения многих проблем SO я сбрасываю position поле до нуля, чтобы начать чтение. Как только это будет сделано:

  • влияет ли это на то, где находится писатель этого потока собираетесь попытаться поместить данные? Нужно ли мне самому отслеживать последнюю позицию записи? (т. е. если я установлю нулевую позицию для чтения, начнет ли писатель перезаписывать все с первого байта?)
  • если да, мне нужен семафор/блокировка вокруг этого поля "позиция" (подкласс, возможно?) из-за моих двух потоков доступа к нему?
  • если я не обрабатываю это свойство, писатель просто переполняет буфер?

возможно, я не понимаю Сам поток-я рассматриваю его как трубу FIFO: засуньте данные с одного конца и высосите их с другого. Если это не как это, то я должен продолжать копировать данные мимо моего последнего чтения (т. е. с позиции 0x84) обратно в начало моего буфера?

Я серьезно пытался исследовать все это в течение некоторого времени, но я новичок .Сеть. Возможно, у потоков есть долгая, гордая (недокументированная) история, которую все остальные неявно понимают. Но для новичка это словно прочитав инструкцию к вашей машине и выяснить:

педаль акселератора влияет на объем топлива и воздуха, подаваемого на топливные форсунки. Это не влияет на объем развлекательной системы или давление воздуха в любой из шин, если они установлены.

технически верно, но серьезно, то, что мы хотим знать, что если мы размажем его на пол вы идете быстрее..

изменить - больше Картина

у меня данные из последовательного порта, сокета или файла, и есть поток, который сидит там ждет новые данные, и записывать их в один или несколько потоков - все одинаковые.
Один из этих потоков я могу получить доступ из сеанса telnet с другого ПК, и все работает нормально.
Проблема, с которой я сейчас сталкиваюсь, - это анализ данных в коде в той же программе (в другом дублированном потоке). Я дублирую данные в MemoryStream и имею поток, чтобы сидеть и расшифровывать данные и передавать их обратно в пользовательский интерфейс. Этот поток делает dataStream.BeginRead() в свой собственный буфер, который возвращает некоторые(?) объем данных до, но не более

2 ответов


я думаю, что вы ожидаете слишком много от документации. Он говорит вам точно, что все делает, но он не говорит вам много о том, как его использовать. Если вы не знакомы с потоками, чтение только documention не даст вам достаточно информации, чтобы понять, как их использовать.

давайте посмотрим, что говорится в документации:

"при переопределении в производном классе, получает или задает позицию в текущий поток."

это "стандартная документация говорит" о том, что свойство предназначено для отслеживания положения в потоке, но что Stream сам класс не обеспечивает фактическую реализацию этого. Реализация заключается в классах, производных от Stream класс, как FileStream или MemoryStream. У каждого есть своя система сохранения позиции, потому что они работают против совершенно разных спины концы.

может быть даже реализация потоков, где Position свойство не имеет смысла. Вы можете использовать CanSeek свойство, чтобы узнать, поддерживает ли реализация потока позицию.

" свойство Position не сохраняет отслеживание количества байтов из поток, который был уничтожен, пропустил, или оба."

это означает, что Position свойство представляет абсолютное положение в задней части реализация, это не просто счетчик того, что было прочитано или написано. Методы чтения и записи потока используют положение, чтобы отслеживать, где читать или писать, это не наоборот.

для реализации потока, который не поддерживает позицию, он все равно мог бы вернуть, сколько байтов было прочитано или записано, но это не так. The Position свойство должно отражать фактическое место в данных, и если оно не может этого сделать, оно должно бросить NotSupportedException исключение.

теперь давайте посмотрим на ваш случай:

С помощью StreamReader и StreamWriter против того же потока сложно и в основном бессмысленно. Поток имеет только одну позицию, которая будет использоваться как для чтения, так и для записи, поэтому вам придется отслеживать две отдельные позиции. Кроме того, вам нужно будет очистить буфер после каждой операции чтения и записи, чтобы в буферах ничего не осталось и Position потока в актуальном состоянии, когда вы извлечь его. Это означает, что StreamReader и StreamWriter не может использоваться по назначению и действует только как обертка вокруг потока.

если вы используете StreamReader и StreamWriter из разных потоков, вы должны синхронизировать операции. Два потока не могут использовать поток одновременно, поэтому операция чтения/записи будет делать:

  • замок
  • установить положение потока из локального копия
  • читать/писать
  • очистить буфер
  • получить положение потока в локальную копию
  • end lock

поток можно использовать в качестве буфера FIFO таким образом, но есть и другие способы, которые могут быть лучше подходят для ваших нужд. А Queue<T> например, работает как буфер FIFO в памяти.


  • позиция является "курсором" для записи и чтения. Так что да, после сброса Position свойство до 0, он начнет перезапись существующих данных
  • вы должны быть осторожны при работе с потоком из нескольких потоков в первую очередь, если честно. Неясно, написали ли вы новый подкласс потока или вы просто клиент существующего потока, но в любом случае вам нужно быть осторожным.
  • неясно, что вы подразумеваете под "Если я не управляю этой собственностью" - что вы подразумеваете под "управляю" здесь? Опять же, это помогло бы, если бы Вы были яснее в том, что вы делаете.

A Stream мая действовать как труба... это действительно зависит от того, что вы делаете с ним. Неясно, что вы подразумеваете под "Я должен продолжать копировать данные после моего последнего чтения" - и неясно, что вы подразумеваете под своим буфером.

если бы вы могли дать представление о большей картине того, чего вы пытаетесь достичь, это действительно поможет.