Why does MemoryStream Position property change with SetLength and become immutable? - c#

There's trouble using the System.IO.MemoryStream class.
After creating it, like so:
var memory = new MemoryStream();
it then sets the length of some bytes to write into it.
var length = 181;
memory.SetLength( length);
Then in the debugger, the memory shows the Length and
Position BOTH set to 181. In separate simply test program
it property shows Position still at zero after SetLength().
Furthermore, if I change the Position property to 0 using
the debugger or by adding a line of code, it ignores
and still shows 181 as the position property. Thus it
behaves as if immutable.
However, again in a simple unit test, this works as expected.
At first, this appeared to be a threading issue as
if MemoryStream isn't thread safe. But in the debugger,
I froze all other threads before calling any of this code.
And it still fails as above.
Well, this is the most bizarre. Any ideas what to try?

I don't see the same thing as you. If I create a console application with the following code in Main:
var x = new MemoryStream();
x.SetLength(181);
..and trace past the call to SetLength, the debugger shows Length equal to 181 and Position equal to 0. You must have something else affecting your stream object.

Actually, figured out the problem. First clue was that it only happened in the debugger.
The cause was the the ToString() method was overridden.
It was reading the memory and displaying it in the debugger. That was reading from the memory and therefore modifying the Position.
Problem solved.
Thanks.

Related

DragEventArgs.GetPosition always .12?

I have a strange behavior of a "Point"-object.
I use a Drag'n'Drop and on the drop I catch the DragEventArgs as the simple variable 'e'. Later I call this line:
Point mc = e.GetPosition(ShelfGrid);
And that leads to a nearly correct result. The mc.X is always .0, if 3.0 or 287.0 or 699.0, but the mc.Y is always .12. So the results from the mc.X taken would seem like 3.12, 287.12 and 699.12.
Now my question: "Why?"
There has to be a reason for the .12, hasn't it?
I guess, that's the Y position of your debugging code line. Having different X values means you scroll the debug code line up and down. Just write the point values to output window instead of debug points and see.

Stream.Seek(0, SeekOrigin.Begin) or Position = 0

When you need to reset a stream to beginning (e.g. MemoryStream) is it best practice to use
stream.Seek(0, SeekOrigin.Begin);
or
stream.Position = 0;
I've seen both work fine, but wondered if one was more correct than the other?
Use Position when setting an absolute position and Seek when setting a relative position. Both are provided for convenience so you can choose one that fits the style and readability of your code. Accessing Position requires the stream be seekable so they're safely interchangeable.
You can look at the source code for both methods to find out:
Position property
https://referencesource.microsoft.com/#mscorlib/system/io/memorystream.cs,320
Seek method
https://referencesource.microsoft.com/#mscorlib/system/io/memorystream.cs,482
The cost is almost identical (3 ifs and some arithmetics). However, this is only true for jumping to absolute offsets like Position = 0 and not relative offsets like Position += 0, in which case Seek seems slightly better.
However, you should keep in mind that we are talking about performance of a handful of integer arithmetics and if checks, that's like not even accurately measureable with benchmarking methods. Like others already pointed out, there is no significant/detectable difference.
If you are working with files (eg: with the FileStream class) it seems Seek(0, SeekOrigin.Begin) is able to keep internal buffer (when possible) while Position=0 will always discard it.

BufferedStream Seek Returns Different Results

Very strange behavior
If I create a bufferedstream on top of a file and then seek to an offset I get a block of bytes back
If I move the debugger back to the seek and re-seek I get an extra two characters
I ve triple checked this
Can there possibly be a bug with this class ?
If I reseek back to position I expect to get the same - The file has not changed - I open it in read only mode and I seek based on Origin
Reproduction:
bufferedStream.Seek(100,0, 100)
bufferedStream.Reade(buffer, 0, 100)
is different to what you get from here
bufferedStream.Seek(100,0, 100)
bufferedStream.Reade(buffer, 0, 100)
First off, it is hard to know if they are the same without checking the return value fro Read - is it possible they are just choosing different chunks? (perfectly valid; it is your job to ensure you loop over Read until you have enough data, or EOF).
However, I wonder if a BOM is involved here - especially if you are sitting a text-reader on top of this. Simply, a reader expects the BOM at the start; so it may well hide it the first time through. But if you rewind the stream while using the same reader/decoder, it won't be expecting a BOM, so will try to report it as character data (or throw an error, depending on the configuraion).

StreamReader issue

if I put a debuger from starting line one of this code and step through i dont get anything
event after the line
xmlData = reader.ReadToEnd();
but if I have debugger on the last line of this code.. where the brace closes, I get everything. i dont know if this only the debuger acting crazy, or a real thing
using (StreamReader reader = new StreamReader(context.Request.InputStream))
{
xmlData = reader.ReadToEnd();
}
Can anyone tell me whats going on. cause sometimes i am not able to get any data from streamreader, even though the data is sent correctly.
Thanks
The reader isn't going to perform the actual "read" until the ReadToEnd method is called. What are you trying to do?
If you put a breakpoint on a line the break occurs before that line gets executed, so it's no surprise that you don't get any data.
But I suspect what you mean is that you place a breakpoint and then step through the code slowly until you reach the end and then check the contents of the variable and find that they are empty.
One cause could be a timing issue. It could be that the service you are reading from has timed out.
Another cause could be a race-condition in your code.
One other unexpected thing that can catch people out is that watches can cause side-effects and stepping through the code causes the watches to be re-evaluated. This can change the state of your program depending on where you put the break-point. You should be careful not to set up a watch on a property that has a side-effect when evaluated.

WaveChannel32 gives me an exception: Offset and length were out of bounds

With the NAudio library I'm trying to mix some audio using a WaveMixerStream32 so I'm using WaveChannel32 to feed it the streams in the proper format. I've got an exception with the following message:
Offset and length were out of bounds
for the array or count is greater than
the number of elements from index to
the end of the source collection.
The minimum example I could make that also throw that error didn't include WaveMixerStream32 at all with took me to the conclusion that the problem was in how I'm using WaveChannel32. The code is this:
var audio = new WaveFileReader(OriginalAudioFileName);
var audio32 = new WaveChannel32(new WaveFileReader(OriginalAudioFileName));
WaveFileWriter.CreateWaveFile(PublicAudioFileName + "audio.wav", audio);
WaveFileWriter.CreateWaveFile(PublicAudioFileName + "audio32.wav", audio32);
audio.wav is generated just fine. audio32.wav is 58 bytes and that line thrown the exception.
What is wrong?
Yes, this is a bug in NAudio. Thanks for reporting it. I've checked in a fix (was a problem with WaveChannel32.GetSourceBuffer). You also need to know that you must set PadWithZeroes to false on your WaveChannel32 before calling WaveFileWriter.CreateWaveFile or you will create a never-ending WAV file, slowly filling up your hard disk.
I got a repro pretty easily. This looks like a basic bug in WaveChannel32.Read(), it doesn't handle .wav files with multiple channels properly. The numBytes argument looks like the size of the file, not the stream.
Let the project owner know. You'll add your issue to a rather long list though.

Categories