0

I'm using C#, WPF, and NAudio.

I play an embedded resource mp3 in the application exe when a key is pressed.

If a key is pressed repeatedly, RAM usage continues to climb past 400MB and never drops.

Using Flush() and Dispose() on the objects doesn't seem to free memory even when GC is called.

This did not used to happen when I played from external resource on the hard drive using string path instead of MemoryStream. It used to stay around 50MB RAM.

memory usage


public static MemoryStream ms = null;    
public static WaveStream wav = null;
public static WaveOutEvent output = null;

// Embedded Resource sound1.mp3
MemoryStream sound1 = new MemoryStream(Properties.Resources.sound1);

// Key Press
//
if (e.Key == Key.Space) {
    ms = new MemoryStream(StreamToBytes(sound1));

    wav = new Mp3FileReader(ms);

    output = new WaveOutEvent();

    output.PlaybackStopped += new EventHandler<StoppedEventArgs>(Media_Ended);
    output.Init(wav);
    output.Play();
}

// MP3 Playback Ended
//
public static void Media_Ended(object sender, EventArgs e)
{
    if (output.PlaybackState == PlaybackState.Stopped)
    {
        ms.Flush();
        ms = null;

        wav.Close();

        output.Dispose();
    }
}

// Convert Stream to Byte Array
//
public static byte[] StreamToBytes(MemoryStream stream)
{
    ...
}

Stream to Byte Array
https://stackoverflow.com/a/1080445/6806643

I convert to Byte Array back to a new Stream or the playback will not layer and will crash if 2 sounds play at once.

Matt McManis
  • 4,475
  • 5
  • 38
  • 93
  • Try a using `using(ms = new MemoryStream(StreamToBytes(sound1)) `block to dispose and set sound1 to null after that block. I would like to see if that works as I am also new to using streams . – Mohamoud Mohamed Mar 09 '18 at 07:37
  • @MohamoudMohamed Each time a key is pressed: `System.ObjectExposedException Cannot access a closed stream` – Matt McManis Mar 09 '18 at 07:53
  • When im using any stream I always use using statements around each and every resource that have try catch / if stream != null to move forward.Right know I think overtime you press a btn your using 3 resources and the garbage collector cant catch up. heres a good link https://stackoverflow.com/questions/234059/is-a-memory-leak-created-if-a-memorystream-in-net-is-not-closed – Mohamoud Mohamed Mar 09 '18 at 08:10
  • @MohamoudMohamed I think it's closing the stream before the sound can begin playing. https://i.imgur.com/LXq8Fxh.png – Matt McManis Mar 09 '18 at 08:17
  • I added this, it Disposes when sound has stopped. It runs smooth, but the memory usage is still high. Garbage Collector never drops it. https://i.imgur.com/wQ2y5ns.png – Matt McManis Mar 09 '18 at 08:20
  • Yes remove the static null at the top `public static MemoryStream ms = null; ` and use using(MemoryStream ms = new MemoryStream()) , I dont want to tell you the wrong thing because Im new with streams too but overiding the behavior of dispose should use the disposable pattern..here is a link https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern – Mohamoud Mohamed Mar 09 '18 at 08:24
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/166517/discussion-between-mohamoud-mohamed-and-matt-mcmanis). – Mohamoud Mohamed Mar 09 '18 at 08:25

1 Answers1

1

It's because you clicking space bar too fast :)

Each key click overwrites variables with new values. So when you click space bar 10 times in few seconds it will create 10 resources. But you keep reference to only last one created. When Media_Ended will start incoming, it will try to dispose only latest created resource.

apocalypse
  • 5,764
  • 9
  • 47
  • 95