开发者

C# Thread Queue Synchronize

开发者 https://www.devze.com 2022-12-25 02:19 出处:网络
Greetings, I am trying to play some audio files without holding up the GUI. Below is a sample of the code:

Greetings, I am trying to play some audio files without holding up the GUI. Below is a sample of the code:

if (audio)
{
    if (ThreadPool.QueueUserWorkItem(new WaitCallback(CoordinateProc), fireResult))
    {

    }
    else
    {
        MessageBox.Show("false");
    }
}

if (audio)
{
    if (ThreadPool.QueueUserWorkItem(new WaitCallback(FireProc), fireResult))
    {

    }
    else
    {
         MessageBox.Show("false");
    }
}

if (audio)
{
    if (ThreadPool.QueueUserWorkItem(new WaitCallback(HitProc), fireResult))
    {

    }
    else
    {
        MessageBox.Show("false");
    }
}

The situation is the samples are not being played in order. some play before the other and I need to fix this so the samples are played one after another in order.

How do I implement this please?

Thank you.

EDIT: ThreadPool.开发者_如何转开发QueueUserWorkItem(new WaitCallback(FireAttackProc), fireResult);

I have placed all my sound clips in FireAttackProc. What this does not do and I want is: wait until the thread stops running before starting a new thread so the samples dont overlap.


Why not just create one "WorkItem" and do everything there?


You can't guarrantee the order of execution of thread pool threads. Rather than that, as suggested by others, use a single thread to run the procs in order. Add the audio procs to a queue, run a single thread that pulls each proc off the queue in order and calls them. Use an event wait handle to signal the thread each time a proc is added to the queue.

An example (this doesn't completely implement the Dispose pattern... but you get the idea):

public class ConcurrentAudio : IDisposable
{
    public ConcurrentAudio()
    {
        _queue = new ConcurrentQueue<WaitCallback>();
        _waitHandle = new AutoResetEvent(false);
        _disposed = false;
        _thread = new Thread(RunAudioProcs);
        _thread.IsBackground = true;
        _thread.Name = "run-audio";
        _thread.Start(null); // pass whatever "state" you need
    }

    public void AddAudio(WaitCallback proc)
    {
        _queue.Enqueue(proc);
        _waitHandle.Set();
    }

    public void Dispose()
    {
        _disposed = true;
        _thread.Join(1000); // don't feel like waiting forever
        GC.SuppressFinalize(this);
    }

    private void RunAudioProcs(object state)
    {
        while (!_disposed)
        {
            try
            {
                WaitCallback proc = null;

                if (_queue.TryDequeue(out proc))
                    proc(state);
                else
                    _waitHandle.WaitOne();
            }
            catch (Exception x)
            {
                // Do something about the error...
                Trace.WriteLine(string.Format("Error: {0}", x.Message), "error");
            }
        }
    }

    private ConcurrentQueue<WaitCallback> _queue;
    private EventWaitHandle _waitHandle;
    private bool _disposed;
    private Thread _thread;
}


You should have a look at the BackgroundWorker option !

0

精彩评论

暂无评论...
验证码 换一张
取 消