TaskFactory,结束时启动一个新任务

时间:2015-08-27 20:45:56

标签: c# multithreading task-parallel-library task threadpool

我找到了许多使用TaskFactory的方法,但我找不到任何关于启动更多任务和观察何时结束并启动另一个任务的方法。

我总是希望有10个任务正常工作。

我想要这样的东西

int nTotalTasks=10;
int nCurrentTask=0;

Task<bool>[] tasks=new Task<bool>[nThreadsNum];

for (int i=0; i<1000; i++)
{
  string param1="test";
  string param2="test";

  if (nCurrentTask<10) // if there are less than 10 tasks then start another one
    tasks[nCurrentThread++] = Task.Factory.StartNew<bool>(() =>
    {
       MyClass cls = new MyClass();
       bool bRet = cls.Method1(param1, param2, i); // takes up to 2 minutes to finish
       return bRet;
    });

  // How can I stop the for loop until a new task is finished and start a new one?
}

5 个答案:

答案 0 :(得分:4)

查看Task.WaitAny方法:

  

等待任何提供的Task对象完成执行。

文档中的示例:

var t1 = Task.Factory.StartNew(() => DoOperation1());
var t2 = Task.Factory.StartNew(() => DoOperation2());

Task.WaitAny(t1, t2)

答案 1 :(得分:2)

我会结合使用Microsoft的Reactive Framework(NuGet“Rx-Main”)和TPL。它变得非常简单。

以下是代码:

console.log('small'); 
console.log('big');

这里的关键部分是int nTotalTasks=10; string param1="test"; string param2="test"; IDisposable subscription = Observable .Range(0, 1000) .Select(i => Observable.FromAsync(() => Task.Factory.StartNew<bool>(() => { MyClass cls = new MyClass(); bool bRet = cls.Method1(param1, param2, i); // takes up to 2 minutes to finish return bRet; }))) .Merge(nTotalTasks) .ToArray() .Subscribe((bool[] results) => { /* Do something with the results. */ }); ,它限制了并发任务的数量。

如果您需要停止处理部分,只需致电.Merge(nTotalTasks),一切都会为您清理。

如果您想要在生成每个结果时处理它们,您可以像subscription.Dispose()那样更改代码:

.Merge(...)

答案 2 :(得分:1)

这应该是您所需要的,而不是完整的,但您需要做的就是等待第一个完成,然后再运行第二个。

$(function() {
    $("tr").each(function() {
        $(this).find("td:eq(14), td:eq(15)").attr("contentEditable", false);
    });
});

答案 3 :(得分:1)

你见过BlockingCollection班吗?它允许您让多个线程并行运行,您可以等待一个任务的结果执行另一个任务。查看更多信息here

答案 4 :(得分:1)

答案取决于要安排的任务是CPU还是I / O限制。

对于CPU密集型工作,我会使用Parallel.For() API通过MaxDegreeOfParallelism的{​​{1}}属性设置线程/任务的数量

对于I / O绑定工作,并发执行任务的数量可能远远大于可用CPU的数量,因此策略是尽可能依赖异步方法,这样可以减少等待完成的线程总数

  

如何在新任务完成并启动之前停止for循环   新的?

可以使用await:

来限制循环
ParallelOptions

帮助程序类 static void Main(string[] args) { var task = DoWorkAsync(); task.Wait(); // handle results // task.Result; Console.WriteLine("Done."); } async static Task<bool> DoWorkAsync() { const int NUMBER_OF_SLOTS = 10; string param1="test"; string param2="test"; var results = new bool[NUMBER_OF_SLOTS]; AsyncWorkScheduler ws = new AsyncWorkScheduler(NUMBER_OF_SLOTS); for (int i = 0; i < 1000; ++i) { await ws.ScheduleAsync((slotNumber) => DoWorkAsync(i, slotNumber, param1, param2, results)); } ws.Complete(); await ws.Completion; } async static Task DoWorkAsync(int index, int slotNumber, string param1, string param2, bool[] results) { results[slotNumber] = results[slotNumber} && await Task.Factory.StartNew<bool>(() => { MyClass cls = new MyClass(); bool bRet = cls.Method1(param1, param2, i); // takes up to 2 minutes to finish return bRet; })); } 使用TPL.DataFlow组件以及AsyncWorkScheduler

Task.WhenAll()