C# 任务列表同步启动它们-我希望它们一次启动所有任务 private async Task MainTask(取消令牌) { 列表任务=新列表(); 做 { var数据=StaticVariables.AllData; foreach(数据中的var数据块) { 添加((新任务(()=>DoSomething(数据))); } Parallel.ForEach(tasks,task=>task.Start()); 等待任务。何时(任务); 任务。清除(); 等待任务。延迟(2000); }而(!token.IsCancellationRequested); }

C# 任务列表同步启动它们-我希望它们一次启动所有任务 private async Task MainTask(取消令牌) { 列表任务=新列表(); 做 { var数据=StaticVariables.AllData; foreach(数据中的var数据块) { 添加((新任务(()=>DoSomething(数据))); } Parallel.ForEach(tasks,task=>task.Start()); 等待任务。何时(任务); 任务。清除(); 等待任务。延迟(2000); }而(!token.IsCancellationRequested); },c#,task,C#,Task,上述函数应该启动许多DoSomething(task)方法,并同时运行它们DoSomething在返回false之前有2秒的超时时间。经过一些测试,似乎 wait Task.whalll(任务) 及 tasks.Clear() 大约需要2秒*的任务数。看来他们是这样做的: 启动任务 2秒后执行或中止 开始下一个任务 我怎样才能使它们同时启动并同时执行操作 编辑 这样做: wait Task.whalll(data.Select(dataPiece=>Task.Run(()=>DoSomet

上述函数应该启动许多
DoSomething(task)
方法,并同时运行它们
DoSomething
在返回
false
之前有2秒的超时时间。经过一些测试,似乎

wait Task.whalll(任务)

tasks.Clear()

大约需要2秒*的任务数。看来他们是这样做的:

  • 启动任务
  • 2秒后执行或中止
  • 开始下一个任务
我怎样才能使它们同时启动并同时执行操作

编辑

这样做:

wait Task.whalll(data.Select(dataPiece=>Task.Run(()=>DoSomething(dataPiece)))


导致糟糕的性能(完成旧代码大约需要25秒,完成此代码需要115秒)

您在这里看到的问题是由于线程池保持了准备运行的线程的最小数量。如果线程池需要创建的线程超过该最小数量,则会在创建每个新线程之间故意引入1秒延迟

这样做是为了防止像“线程踩踏”这样的事情用许多同时创建的线程淹没系统

您可以使用更改最小线程限制。但是,不建议这样做,因为这会破坏预期的线程池操作,并可能导致其他进程减慢

如果您确实必须这样做,下面是一个控制台应用程序示例:

private async Task MainTask(CancellationToken token)
{
    List<Task> tasks = new List<Task>();
    do
    {
        var data = StaticVariables.AllData;

        foreach (var dataPiece in data)
        {
            tasks.Add((new Task(() => DoSomething(data))));
        }

        Parallel.ForEach(tasks, task => task.Start());
        await Task.WhenAll(tasks);
        tasks.Clear();
        await Task.Delay(2000);
    } while (!token.IsCancellationRequested);
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用系统线程;
使用System.Threading.Tasks;
名称空间控制台AP3
{
班级计划
{
静态秒表sw=Stopwatch.StartNew();
静态void Main()
{
runTasks();
setMinThreadPoolThreads(30);
runTasks();
}
静态void setMinThreadPoolThreads(int计数)
{
WriteLine(“\n将最小线程池线程设置为{0}.\n”,计数);
int workerThreads,completionPortThreads;
GetMinThreads(out workerThreads,out completionPortThreads);
SetMinThreads(计数,completionPortThreads);
}
静态void runTasks()
{
var sw=Stopwatch.StartNew();
Console.WriteLine(“\n启动任务”);
var任务=测试(20);
WriteLine(“等待任务完成”);
task.Wait();
Console.WriteLine(“在”+sw.经过后完成);
}
静态异步任务测试(int n)
{
var tasks=新列表();
对于(int i=0;i
如果运行它,您将从输出中看到,在设置最小线程池大小之前运行
test()
,任务将花费大约10秒的时间(并且您将看到任务开始时间之间的延迟在前几个任务之后增加)

将最小线程池线程数设置为30后,新任务启动之间的延迟将大大缩短,运行
test()
的总时间将降至5秒左右(在我的电脑上-您的可能会有所不同!)

但是,我只想重申,设置最小线程池大小不是一件正常的事情,应该谨慎处理。正如Microsoft文档所述:

默认情况下,最小线程数设置为系统上的处理器数。您可以使用SetMinThreads方法增加最小线程数。但是,不必要地增加这些值可能会导致性能问题。如果同时启动的任务太多,则所有任务都可能看起来很慢。在大多数情况下线程池使用它自己的线程分配算法会表现得更好。将最小值减少到处理器数量以下也会影响性能


您在这里看到的问题是由于线程池保持了准备运行的最小线程数。如果线程池需要创建的线程数超过该最小值,则会在创建每个新线程之间故意引入1秒延迟

这样做是为了防止像“线程踩踏”这样的事情用许多同时创建的线程淹没系统

您可以使用更改最小线程限制。但是,不建议这样做,因为这会破坏预期的线程池操作,并可能导致其他进程减慢

如果您确实必须这样做,下面是一个控制台应用程序示例:

private async Task MainTask(CancellationToken token)
{
    List<Task> tasks = new List<Task>();
    do
    {
        var data = StaticVariables.AllData;

        foreach (var dataPiece in data)
        {
            tasks.Add((new Task(() => DoSomething(data))));
        }

        Parallel.ForEach(tasks, task => task.Start());
        await Task.WhenAll(tasks);
        tasks.Clear();
        await Task.Delay(2000);
    } while (!token.IsCancellationRequested);
}
使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用系统线程;
使用System.Threading.Tasks;
名称空间控制台AP3
{
班级计划
{
静态秒表sw=Stopwatch.StartNew();
静态void Main()
{
runTasks();
setMinThreadPoolThreads(30);
runTasks();
}
静态void setMinThreadPoolThreads(int计数)
{
await Task.WhenAll(data.Select(dataPiece => Task.Run(() => DoSomething(dataPiece)).ToList());