SoundPlayer causing Memory Leaks?

2019-04-05 23:26发布

I'm writing a basic writing app in C# and I wanted to have the program make typewriter sounds as you typed. I've hooked the KeyPress event on my RichTextBox to a function that uses a SoundPlayer to play a short wav file every time a key is pressed, however I've noticed after a while my computer slows to a crawl and checking my processes, audiodlg.exe was using 5 GIGABYTES of RAM.

The code I'm using is as follows:

I initialise the SoundPlayer as a global variable on program start with

SoundPlayer sp = new SoundPlayer("typewriter.wav")

Then on the KeyPress event I simply call

sp.Play();

Does anybody know what's causing the heavy memory usage? The file is less than a second long, so it shouldn't be clogging the thing up too much.

8条回答
SAY GOODBYE
2楼-- · 2019-04-05 23:46

Try disposing the SoundPlayer after playing the sound. Then run the Garbage Collector. If it still consumes additional memory, something really nasty is happening and you should run the tests on another computer.

查看更多
何必那么认真
3楼-- · 2019-04-05 23:47

I've done with this sample. WWFM (aka "Worked Well For Me). Try searching errors in your code (which, i'm almost sure, is pure enough) or another sound file.

查看更多
Viruses.
4楼-- · 2019-04-05 23:52

Don't use SoundPlayer - use the waveOut... API instead:

http://www.codeproject.com/Articles/4889/A-full-duplex-audio-player-in-C-using-the-waveIn-w

SoundPlayer is more like a toy than a production-ready component, although I'm sure the MS intern that wrote it meant well. :)

Update: if you use the linked sample and get familiar with the code, you'll see what's probably wrong with the SoundPlayer implementation. Playing audio with the waveOut... functions involves two in-memory buffers: one small one for the header, and one potentially large buffer than contains the actual sample data. The hotfix article you linked to mentions the leak of a few hundred bytes each time Play is called, which means the code is probably instantiating a new header each time and then not disposing of it properly. (This is assuming SoundPlayer wraps the waveOut... API - I don't know whether this is the case or not)

Programmers take for granted the maxim "don't reinvent the wheel". Well, sometimes the wheel desperately needs reinventing.

查看更多
萌系小妹纸
5楼-- · 2019-04-05 23:57

You should try using()

using(SoundPlayer sp = new SoundPlayer("typewriter.wav")) {
   sp.Play();
}

when process finish sp.Play() memory return to your system automatics.

查看更多
神经病院院长
6楼-- · 2019-04-06 00:03

This isn't strictly speaking an answer, so I won't confirm this as the accepted answer to my question, but it is a solution for those who have had the same problems (and also confirms it's not my system at fault)

I decided to implement the sound using ManagedDirectX's AudioPlayback library, which is about as easy to use as SoundPlayer, but has successfully solved my problem.

For those who want to know, the code is simple:

1) Add a reference to the audioplayback dll.

2) Create an Audio object (I named mine sound), make it a variable on your form so you can refer to it again, use the constructor to set the filename it should play

3) Play the file with sound.Play();

4) If you need to play the file again, use the following line:

sound.SeekCurrentPosition(0, SeekPositionFlags.AbsolutePositioning);

It's fairly fast, and fairly good. There'll be memory issues if you need a lot of different sound effects, because they'll all constantly be in memory, but if you need one sound to play a lot, this one will do it without ballooning your Audiodlg.exe

查看更多
干净又极端
7楼-- · 2019-04-06 00:04

Try using the Load method of the sound player to load the sound, and then call play. Play uses a second thread to load(if not loaded already) and play the file.

Maybe the constructor does not load the file initially (which I think is quite possible) , it mearly associates the player with the sound file name.

查看更多
登录 后发表回答