C# 线程队列同步

发布于 08-26 16:42 字数 815 浏览 16 评论 0原文

您好,我正在尝试在不停止 GUI 的情况下播放一些音频文件。下面是代码示例:

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 中。这不会做但我想要的是:等到线程停止运行后再启动新线程,这样样本就不会重叠。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

对你再特殊2024-09-02 16:42:51

为什么不只创建一个“WorkItem”并在那里完成所有操作呢?

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

猫腻2024-09-02 16:42:51

您无法保证线程池线程的执行顺序。而不是像其他人建议的那样,使用单个线程按顺序运行过程。将音频过程添加到队列中,运行一个线程,按顺序将每个过程从队列中拉出并调用它们。每次将过程添加到队列时,使用事件等待句柄向线程发出信号。

一个例子(这并没有完全实现 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;
}

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;
}
木緿2024-09-02 16:42:51

您应该查看 BackgroundWorker 选项!

You should have a look at the BackgroundWorker option !

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文