使用TPL进行协作式多任务处理

Jev*_*sov 7 c# python multithreading scheduled-tasks task

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

  1. Task队列
  2. 每个Task队列都执行一个IronPython脚本
  3. 在IronPython脚本里面我们调用了C#类方法,它是同步点并且应该转移Task(IronPython执行)到等待状态

我们想做什么:

  1. 我们想要进行无限循环,它将遍历Tasks队列
  2. 当我们得到一个时,Task我们尝试执行它
  3. 在PythonScript中,我们想要调用C#方法并将此脚本转移到等待状态.但不要将其从队列中删除.
  4. 在下一次迭代时,当我们得到另一个时,Task我们检查它是否处于等待状态.如果是这样,我们将其唤醒并尝试执行.
  5. 在每一刻我们应该只有一个活跃的 Task
  6. 最后我们要测量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();
        }
   }
Run Code Online (Sandbox Code Playgroud)

自定义任务调度程序,它有一个_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);
}
Run Code Online (Sandbox Code Playgroud)

也许有人有更好的想法?

小智 2

听起来您会很适合使用 .NET 4 内置于一些集合中的生产者/消费者模式。

查看 Microsoft 提供的免费 PDF《并行编程模式》中的第 55 页