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

时间:2010-10-13 08:30:28

标签: c# python multithreading scheduled-tasks task

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

  1. Task队列
  2. 此队列中的每个Task执行一个IronPython脚本
  3. 在IronPython脚本中,我们调用C#类方法,它是同步点,应该将Task(IronPython执行)转移到等待状态
  4. 我们想做什么:

    1. 我们想要进行无限循环,这将循环遍历Task队列
    2. 当我们得到一个Task时,我们会尝试执行它
    3. 在PythonScript中,我们要调用C#方法并将此脚本转移到等待状态。但不要将其从队列中删除。
    4. 在下一次迭代时,当我们得到另一个Task时,我们检查它是否处于等待状态。如果是这样,我们将其唤醒并尝试执行。
    5. 每一刻我们都应该只有一个活跃的Task
    6. 最后我们要衡量每秒可执行的Task
    7. 我真的不知道合作多任务是什么? 我们正在考虑自定义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 个答案:

答案 0 :(得分:2)

听起来您可以很好地使用.NET 4内置于少数集合中的生产者/消费者模式。

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