Синхронизация очереди потока C # - PullRequest
1 голос
/ 28 марта 2010

Привет, я пытаюсь воспроизвести некоторые аудиофайлы без поддержки графического интерфейса. Ниже приведен пример кода:

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");
    }
}

Ситуация такова, что сэмплы воспроизводятся не по порядку. некоторые играют раньше других, и мне нужно исправить это, чтобы сэмплы воспроизводились один за другим по порядку.

Как мне это реализовать, пожалуйста?

Спасибо.

РЕДАКТИРОВАТЬ: ThreadPool.QueueUserWorkItem(new WaitCallback(FireAttackProc), fireResult);

Я поместил все свои звуковые клипы в FireAttackProc. Чего это не делает, и я хочу это: подождать, пока поток не остановится, прежде чем начинать новый поток, чтобы примеры не перекрывались.

Ответы [ 3 ]

3 голосов
/ 28 марта 2010

Почему бы просто не создать один "WorkItem" и сделать там все?

1 голос
/ 28 марта 2010

Вы не можете гарантировать порядок выполнения потоков пула потоков. Вместо этого, как предлагают другие, используйте один поток для запуска процедур по порядку. Добавьте аудио-процессы в очередь, запустите один поток, который вытягивает каждый процесс из очереди по порядку и вызывает их. Используйте дескриптор ожидания события, чтобы сигнализировать потоку каждый раз, когда процесс добавляется в очередь.

Пример (это не полностью реализует шаблон Dispose ... но вы поняли идею):

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;
}
0 голосов
/ 28 марта 2010

Вы должны взглянуть на BackgroundWorker вариант!

...