C# 运行大量任务
我想创建大量任务n,并在每个任务I中使用从任务I-1获得的结果 我想到了:C# 运行大量任务,c#,task,stack-overflow,C#,Task,Stack Overflow,我想创建大量任务n,并在每个任务I中使用从任务I-1获得的结果 我想到了: class TaskTest { static int count; public static void Main() { int n = 1000000; var t = Add(n); var sum = t.GetAwaiter().GetResult(); Console.WriteLine("sum is: " + sum); } public static Task<
class TaskTest
{
static int count;
public static void Main()
{
int n = 1000000;
var t = Add(n);
var sum = t.GetAwaiter().GetResult();
Console.WriteLine("sum is: " + sum);
}
public static Task<int> Add(int step)
{
Task t = new Task(() => Add(step));
t.Start();
if (step == 0)
return Task.FromResult(0);
return Task.FromResult(Add(step - 1).Result + 1);
}
static void AddWithLock(int step)
{
if (step == 0)
return;
Interlocked.Increment(ref count);
var t = Task.Factory.StartNew(state => AddWithLock(step - 1), CancellationToken.None);
t.Wait();
}
}
类任务测试
{
静态整数计数;
公共静态void Main()
{
int n=1000000;
var t=加(n);
var sum=t.GetAwaiter().GetResult();
Console.WriteLine(“总和为:+总和”);
}
公共静态任务添加(int步骤)
{
任务t=新任务(()=>添加(步骤));
t、 Start();
如果(步骤==0)
返回Task.FromResult(0);
返回Task.FromResult(添加(步骤-1).Result+1);
}
静态void AddWithLock(int步)
{
如果(步骤==0)
返回;
联锁增量(参考计数);
var t=Task.Factory.StartNew(state=>AddWithLock(步骤-1),CancellationToken.None);
t、 等待();
}
}
使用Add()方法对较小的n值(如1000)有效,但在n=1 000 000时使用StackOwerFlowException失败
Usin AddWithLock()并不是我想要的(它不使用其他任务的结果),虽然它可以处理大量数据,但速度非常慢
那么,如何修改代码,使其适用于n=100万这样的数字
编辑:
我尝试使用TaskCompletionSource,但仍然得到StackOverflowException
public static Task<int> Add2(int step)
{
var tcs = new TaskCompletionSource<int>();
if (step == 0)
tcs.SetResult(0);
else
{
var r = Add2(step - 1).Result;
tcs.SetResult(r + 1);
}
return tcs.Task;
}
公共静态任务Add2(int-step)
{
var tcs=new TaskCompletionSource();
如果(步骤==0)
tcs.SetResult(0);
其他的
{
var r=Add2(步骤-1)。结果;
tcs.SetResult(r+1);
}
返回tcs.Task;
}
如果不使用递归,它就足够好了。它在我的PC(旧i7)上完成大约1000毫秒。没有堆栈爆炸
using System;
using System.Diagnostics;
using System.Threading.Tasks;
namespace ManyTasks
{
class Program
{
public static void Main()
{
int n = 1000000;
Task<int>[] tasks = new Task<int>[n];
var sw = new Stopwatch();
sw.Start();
Task.Factory.StartNew(() =>
{
for (int i = 0; i < n; i++)
{
int j = i;
tasks[i] = new Task<int>(() =>
{
if (j == 0)
return 1;
var result = tasks[j - 1].Result + 1;
return result;
});
tasks[i].Start();
tasks[i].Wait();
}
}).Wait();
sw.Stop();
Console.WriteLine(tasks[n - 1].Result);
Console.WriteLine($"time: {sw.Elapsed.TotalMilliseconds:0.000}ms");
}
}
}
使用系统;
使用系统诊断;
使用System.Threading.Tasks;
命名空间多任务
{
班级计划
{
公共静态void Main()
{
int n=1000000;
任务[]任务=新任务[n];
var sw=新秒表();
sw.Start();
Task.Factory.StartNew(()=>
{
对于(int i=0;i
{
如果(j==0)
返回1;
var result=tasks[j-1]。result+1;
返回结果;
});
任务[i].Start();
任务[i]。等待();
}
}).Wait();
sw.Stop();
Console.WriteLine(任务[n-1].Result);
WriteLine($“时间:{sw.appeased.total毫秒:0.000}ms”);
}
}
}
这里有一个递归函数,Add
调用Add
它调用Add
等等。你不能简单地在一百万级的深度上做这件事。我有太多的问题,这段代码无法回答任何问题。例如,为什么要创建任务t
并启动它?你不用它。此外,Task.FromResult
不会启动另一个任务,因此实际上您只是递归调用Add
。首先,提出一个使用任务的合理理由。首先,你的代码可以用普通循环实现,这意味着我想知道你为什么要使用任务。你想解决的实际问题是什么?或者这只是一个学术练习,看看你的堆栈有多大?要让它工作,你需要删除递归。问题不在于任务。目标正如我所说的:创建100万个任务,并在每个任务中使用上一个创建的任务的结果。我不是在试图解决现实世界的问题。我只想在大量任务之间及时传递结果。这个想法来自这里: