我有一个递归程序,它自称是一个新任务。
完整示例代码:
using System;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
public class Class0
{
const int initialTasks = 1;
static void Main()
{
Class1 myClass1 = new Class1();
myClass1.Go(initialTasks);
Console.ReadLine();
}
}
public class Class1
{
const int childrenTasks = 100;
const int fibonacciTarget = 1234567;
double taskCount = 0;
public void Go(int tasks)
{
for (int index = tasks; index > 0; index--)
{
double taskID = GetID();
Console.WriteLine("Enqueue: {0}", taskID);
Task mainTask = new Task(() => MainTask(taskID));
mainTask.Start();
}
}
private void MainTask(double taskID)
{
FibonacciToTarget(fibonacciTarget);
Go(childrenTasks);
Console.WriteLine("DONE : {0}", taskID);
}
//cpu bound task
private static void FibonacciToTarget(int target)
{
int a = 1;
int b = 1;
int x;
loop:
if (b > target) { return; }
x = a + b;
a = b;
b = x;
goto loop;
}
private double GetID()
{
lock (this)
{
taskCount++;
return taskCount;
}
}
}
}
运行良好一段时间,但最终会产生太多任务。
如果完成/启动时间超过1分钟,是否有办法让排队的任务死亡?
我读过这个:Cancel task by time 它似乎依赖于已经运行的任务,但是我的程序是cpu绑定的,因此任务在排队后可能甚至不会开始运行一分钟。
答案 0 :(得分:0)
您的代码正在使用一段时间消耗CPU时间后生成100个其他任务。这会产生积极的反馈(行动1导致行动2,导致行动1)。如果您在开始吃掉掉内存之前没有关闭程序,那么您将无法使计算机无法使用。
如果完成/启动时间超过1分钟,是否有办法让排队的任务死亡?
最简单的方法是使用您已阅读的问题中的一个答案中提到的CancellationTokenSource
课程。但如果我理解你的话,那只会让程序在一分钟后自杀。
它是一种计算通过虚拟道路网络的旅行成本的方法。每次在网络上进行计算时,都会增加该路线的成本,从而对路线成本进行排序。
您想要实施的是一种计算旅行商问题解决方案的算法。递归地做它根本不是一个好主意,因为解决复杂性是天高(n-1)!
使用动态编程(如果您真的想要获得多线程,则使用与工作线程并行化的数组访问)来解决此问题。搜索解决它的最佳算法。如果你真的想要一种快速结束程序的方法,那么所有工作线程都会共享CancellationTokenSource
类,并且在每个计算周期之前都会检查IsCancellationRequested
属性。