使用 TPL 的协同多任务处理

Posted

技术标签:

【中文标题】使用 TPL 的协同多任务处理【英文标题】:Cooperative multitasking using TPL 【发布时间】:2011-04-24 17:30:51 【问题描述】:

我们正在移植建模应用程序,它使用 IronPython 脚本在建模过程中进行自定义操作。现有应用程序在单独的线程中执行每个 Python 脚本,并为此使用协作模型。现在我们要将其移植到 TPL,但首先我们要测量上下文切换 . 基本上,我们现在拥有的:

    Tasks 队列 此队列中的每个 Task 执行一个 IronPython 脚本 在 IronPython 脚本中,我们调用 C# 类方法,这是同步点,应该将 Task(IronPython 执行)转移到等待状态

我们想做什么:

    我们要做一个无限循环,它会遍历Tasks 队列 当我们得到一个 Task 时,我们会尝试执行它 在 PythonScript 中,我们要调用 C# 方法并将此脚本转换为等待状态。但不会将其从队列中移除。 在下一次迭代中,当我们得到另一个Task 时,我们检查它是否处于等待状态。如果是这样,我们将其唤醒并尝试执行。 在每一刻我们应该只有一个活跃的Task 最后,我们要测量每秒可以执行多少个Task

我真的不知道这与协作式多任务处理有关吗? 我们正在考虑自定义TaskScheduler,这是个好方法吗?或者有人知道更好的解决方案吗?

谢谢。

更新:

好的,例如,我有这样的代码:

public class CooperativeScheduler : TaskScheduler, IDisposable
    
        private BlockingCollection<Task> _tasks;

        private Thread _thread;

        private Task _currentTask;

        public CooperativeScheduler()
        
            this._tasks = new BlockingCollection<Task>();
            this._thread = new Thread(() =>
                
                    foreach (Task task in this._tasks.GetConsumingEnumerable())
                    
                        this._currentTask = task;

                        TryExecuteTask(this._currentTask);
                    
                
            );

            this._thread.Name = "Cooperative scheduler thread";

            this._thread.Start();
        

        public void SleepCurrentTask()
        
            if (this._currentTask != null)
            
                // what to do here?
            
        

        protected override IEnumerable<Task> GetScheduledTasks()
        
            return this._tasks.ToArray<Task>();
        

        protected override void QueueTask(Task task)
        
            // No long task
            this._tasks.Add(task);
        

        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
        
            throw new NotImplementedException();
        

        public void Dispose()
        
            this._tasks.CompleteAdding();
            this._thread.Join();
        
   

自定义任务计划程序,它有一个_thread 用于任务执行和_currentTask 字段用于运行任务,还有SleepCurrentTask 在此方法中我想暂停当前任务执行,但我不知道如何。

客户端代码很简单:

    CancellationTokenSource tokenSource = new CancellationTokenSource();
    Application app = Application.Create();


    Task task = Task.Factory.StartNew(() =>
    
        app.Scheduler.SleepCurrentTask();
    ,
     tokenSource.Token, TaskCreationOptions.None, app.Scheduler);

也许有人有更好的想法?

【问题讨论】:

【参考方案1】:

听起来您最好使用 .NET 4 已内置到一些集合中的生产者/消费者模式。

查看 Microsoft 提供的免费 PDF 中的第 55 页,Patterns of Parallel Programming

【讨论】:

以上是关于使用 TPL 的协同多任务处理的主要内容,如果未能解决你的问题,请参考以下文章

python中的super()用法以及多继承协同任务

Phaser多任务协同的神器

Phaser多任务协同的神器

协同任务基于matlab蚁群算法多组群UAV协同任务路径规划含Matlab源码 1578期

协同任务基于matlab VFH算法多无人机协同控制技术含Matlab源码 1999期

CyclicBarrier多任务协同的利器