2
Reply

How to work with unmanaged resourcres (SoundPlayer class)

Stefan B

Stefan B

Mar 19 2016 1:45 PM
349
Hi together,

I have been working on a project which includes something close to a virtual keyboard in its GUI. So there are some Button-like objects you can click and something happens in the background. I now want them to make a clicking sound (async) (e.g. playing a .wav I have) when clicked. If another button gets clicked while the sound is still playing, it shall just stop and start the sound again at the begining.
Now this sounds rather easy, but there seems to be a devil in the details, since I can't get rid of a potential memory problem due to the wrapped unmanaged resource.
Round about everywhere you can read, that you need to dispose your SoundPlayer object or you will run out of memory since GC won't collect the unmanaged resource (Sound). Though, since I can not tell when my sound ends playing, I can not dispose my object properly.
The problems of different solutions are described pretty well in this topic:
http://stackoverflow.com/questions/1161229/how-to-use-system-media-soundplayer-to-asynchronously-play-a-sound-file?lq=1
Now I am not really sure why I should even run into a problem. If I implement something like this:
 
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Linq;  
  7. using System.Text;  
  8. using System.Windows.Forms;  
  9. using System.Media;  
  10.   
  11. namespace WindowsFormsApplication1  
  12. {  
  13.     public partial class Form1 : Form  
  14.     {  
  15.   
  16.         SoundPlayer player = new SoundPlayer(Resource1.test);  
  17.         public Form1()  
  18.         {  
  19.             InitializeComponent();  
  20.   
  21.         }  
  22.   
  23.         private void Form1_Load(object sender, EventArgs e)  
  24.         {  
  25.             player.Load();  
  26.         }  
  27.   
  28.         private void button1_Click(object sender, EventArgs e)  
  29.         {  
  30.             player.Play();  
  31.             this.button1.Text = (Int32.Parse(this.button1.Text) + 1).ToString();  
  32.         }  
  33.   
  34.         private void timer1_Tick(object sender, EventArgs e)  
  35.         {  
  36.             this.button1.PerformClick();  
  37.         }  
  38.     }  

 
Now in my understanding I create the player object once, which will wrap the test sound resource. I never manually dispose it, since there is no telling when to do so. But since I always use the same object, I still should not run into a memory leak. Or is this still a problem and memory gets blocked with each call of play?

What are good ways to get rid of this? It should solve the problem if I just get the sound from a file, shouln't it? Would I still want to use a "using" around the SoundPlayer object then or is it fine to just create one in this case?

I could of course dispose and reload before every click, the sound is just a few KB big, but that is not really the spirit of a good solution...

Thanks a lot for every advice,
Cheers
Stefan  

Answers (2)