Trying to play .wav files in a thread safe queue. Calls may be triggered at random by any thread but must play in sequence. Problem is when I call Play(string[] files)
with say 3 file names (currently testing from the UI thread), the last file is played 3 times, and the two first never played. Can't see what causes this..?
Would appreciate suggestion for easier way to do this, but mainly like to know why this doesn't work.
public class Audio
{
static ActionQueue actionQueue;
public static string MediaFolder { get; set; }
private static object syncroot = new object();
static Audio()
{
actionQueue = new ActionQueue();
}
/// <summary>
/// Plays .wav in async queue.
/// </summary>
/// <param name="fileName"></param>
public static void Play(string fileName)
{
actionQueue.Add(() => PlaySound(fileName));
}
public static void Play(string[] files)
{
Console.WriteLine("ID0: " + Thread.CurrentThread.ManagedThreadId);
foreach (string f in files.ToList())
{
Console.WriteLine("Queue file: " + f);
actionQueue.Add(() => PlaySound(f));
}
}
private static void PlaySound(string f)
{
Console.WriteLine("ID1: " + Thread.CurrentThread.ManagedThreadId);
var fileName = f;
Console.WriteLine("Play queue: " + fileName);
fileName = Path.Combine(MediaFolder, fileName);
if (!Path.HasExtension(fileName))
fileName = fileName + ".wav";
if (!File.Exists(fileName)) return;
string ext = Path.GetExtension(fileName);
if (ext != ".wav") return;
Console.WriteLine("Playing: " + fileName);
SoundPlayer player = new SoundPlayer(fileName);
player.PlaySync();
}
}
public class ActionQueue
{
private BlockingCollection<Action> persisterQueue = new BlockingCollection<Action>();
public ActionQueue( )
{
var thread = new Thread(ProcessWorkQueue);
thread.IsBackground = true;
thread.Start();
}
private void ProcessWorkQueue()
{
while (true)
{
var nextWork = persisterQueue.Take();
nextWork();
}
}
public void Add(Action action)
{
persisterQueue.Add(action );
}
}