【问题标题】:C# Thread Queue SynchronizeC# 线程队列同步
【发布时间】:2011-02-01 18:29:48
【问题描述】:

您好,我正在尝试在不打开 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 中。这没有做的,我想要的是:等到线程停止运行,然后再启动一个新线程,这样样本就不会重叠。

【问题讨论】:

  • 线程是为并发执行任务而设计的,一个接一个的播放声音不是并发执行。您可能有在单独的线程上播放声音的正确想法,但不是 each 声音。 Petoj 是正确的。
  • 也可以使用线程,这样主 GUI 线程在等待数据时不会冻结。这就是我在这里要做的。

标签: c# threadpool queueuserworkitem


【解决方案1】:

为什么不只创建一个“WorkItem”并在那里做所有事情呢?

【讨论】:

  • 我是新手。什么是 WorkItem?
  • ThreadPool.QueueUserWorkItem(new WaitCallback(HitProc), fireResult) 你添加一个“WorkItem”
  • 啊,你的意思是把所有的事情合二为一(Proc)。那是可能的,但我只是想知道是否可以订购一组线程来执行。
  • 他们可以,但在你的情况下,我不知道这样做的原因... google c# Thread Synchronization...
【解决方案2】:

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

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

【讨论】:

  • 是的,我相信您正确理解了我的情况。我仍然对您的代码不知所措。我明白了这个想法,但没有实现,因为我是初学者。谢谢,如果您愿意,请随时进一步扩展您的帖子。我非常欢迎它。
【解决方案3】:

您应该看看BackgroundWorker 选项!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多