c# - 实现线程队列

标签 c# wpf multithreading

考虑这个例子: 当用户单击按钮时,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;
        }
    }
}

关于c# - 实现线程队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9234536/

相关文章:

wpf - 在MVVM View 模型中哪里处理逻辑?

arrays - 使用 .NET 多线程运行同一应用程序的多个实例

c# - 如何通过 LINQ 在二维数组中进行搜索?

c# - zip 文件编码 (C#/ionic-zip)

c# - 还有另一种测试枚举位域的方法吗?

WPF 动画仅触发一次

c# - MVVM Light,将 RelayCommand<T> 与返回数据的方法一起使用

java - 传递给 CompletableFuture SupplyAsync Executors.newFixedThreadPool(10) 或 new ForkJoinPool(10) 哪个执行器更好

java - Java 7 中的获取或创建模式?

c# - 需要工作流程编辑软件 - 推荐