正在实现线程队列

本文关键字:队列 线程 实现 | 更新日期: 2023-09-27 18:24:00

考虑以下示例:当用户单击按钮时,ClassA会快速触发OnUserInteraction事件10次ClassB附加到此事件,并在其事件处理程序中激发ClassC的Render方法。在Render方法中,执行AxisAngleRotation3D,但每个动画持续1秒。

在这个场景中,所有10个AxisAngleRotation3D动画几乎同时执行,但我希望它们一个接一个地执行。根据我对线程的理解,我可能必须在ClassB中实现一个线程队列,其中AxisAngleRotation3DCompleted事件表示允许激发下一个事件。。。?

这是正确的吗?我该如何做到这一点?

正在实现线程队列

有一个任务队列。简单地说,有一个ConcurrentQueue<Func<bool>>字段或类似字段,并根据需要向其中添加任务。然后让任务执行线程将Func<bool>委托从队列中弹出并调用它们。如果它们是真的,它们就完了。如果返回false,请将它们重新添加到队列中,因为它们当时无法完成。

这里有一个例子:

using System;
using System.Collections.Concurrent;
using System.Threading;
namespace Example
{
    public class TaskScheduler : IDisposable
    {
        public const int IDLE_DELAY = 100;
        private ConcurrentQueue<Func<bool>> PendingTasks;
        private Thread ExecuterThread;
        private volatile bool _IsDisposed;
        public bool IsDisposed
        {
            get { return _IsDisposed; }
        }
        public void EnqueueTask(Func<bool> task)
        {
            PendingTasks.Enqueue(task);
        }
        public void Start()
        {
            CheckDisposed();
            if (ExecuterThread != null)
            {
                throw new InvalidOperationException("The task scheduler is alreader running.");
            }
            ExecuterThread = new Thread(Run);
            ExecuterThread.IsBackground = true;
            ExecuterThread.Start();
        }
        private void CheckDisposed()
        {
            if (_IsDisposed)
            {
                throw new ObjectDisposedException("TaskScheduler");
            }
        }
        private void Run()
        {
            while (!_IsDisposed)
            {
                if (PendingTasks.IsEmpty)
                {
                    Thread.Sleep(IDLE_DELAY);
                    continue;
                }
                Func<bool> task;
                while (!PendingTasks.TryDequeue(out task))
                {
                    Thread.Sleep(0);
                }
                if (!task.Invoke())
                {
                    PendingTasks.Enqueue(task);
                }
            }
        }
        public void Dispose()
        {
            CheckDisposed();
            _IsDisposed = true;
        }
    }
}

ClassB可以将事件添加到队列中,然后一次呈现一个事件(可能使用计时器从队列中读取)。