【发布时间】:2020-11-24 20:19:04
【问题描述】:
我正在 C# 中同步创建一个列表,但速度很慢。列表中大约有 50 个项目,添加每个项目最多可能需要 20 秒。添加项目的方法可以是异步的,所以我想知道是否可以使用 async/await 以某种方式添加所有项目。
这是一个将 2 个项目同步添加到列表的简单示例。我将如何异步执行?甚至可能吗?如果您尝试同时添加到列表中,您会遇到“冲突”吗?
using System.Threading;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
List<int> lst = null;
lst=GetList();
}
static List<int> GetList()
{
List<int> lst = new List<int>();
//add to list
lst.Add(Task1());
lst.Add(Task2());
//return list
return lst;
}
static int Task1()
{
Thread.Sleep(10000);
return 1;
}
static int Task2()
{
Thread.Sleep(10000);
return 2;
}
}
Compufreak 的答案正是我想要的。我有一个相关的问题,虽然我不确定这是否是我应该问的方式。我将 Compufreak 的代码稍微修改为一种对我来说更有意义的方式,我想知道代码的工作方式是否有任何实际差异。我从 Task1 和 Task2 中取出 async/await 并创建了一个 Task 并将 Task1 和 Task2 作为参数传入。
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
class Program
{
static async Task Main(string[] args)
{
List<int> lst = null;
DateTime StartTime = DateTime.Now;
lst = await GetList();
DateTime EndTime = DateTime.Now;
Console.WriteLine("ran tasks in " + (EndTime - StartTime).TotalSeconds + " seconds");
Console.ReadLine();
}
static async Task<List<int>> GetList()
{
var tasks = new List<Task<int>>();
//add task to list of tasks
tasks.Add(new Task<int>(Task1));
tasks.Add(new Task<int>(Task2));
//start tasks
foreach(Task<int> t in tasks)
{
t.Start();
}
//await results
int[] results = await Task.WhenAll(tasks);
//return list
return results.ToList();
}
static int Task1()
{
Thread.Sleep(10000);
return 1;
}
static int Task2()
{
Thread.Sleep(10000);
return 2;
}
}
【问题讨论】:
-
您应该查看
async/await。它是为这样的场景设计的(或其他 TPL 类型模式,如Parallel.ForEach) -
@tnw 这似乎是一个不同的场景。在我的情况下,每个“添加”大约需要 10 秒来计算要添加的值。
-
@Andy 是的,我尝试使用 async/await 来实现,但我是新手,我什至不确定在这种情况下是否可行。
-
看看下面的答案。这真是一个很好的例子。请记住,Async/Await 模式是一个非常深的兔子洞,但是,它在当今的编码标准中是无价的。最好早点学习。
-
虽然链接的问题在我上次重新投票后发生了变化,但我仍然认为这不是 100% 的匹配。 now linked answer 是关于等待具有不同结果类型的任务。这是关于等待具有相等结果类型的任务。不同之处在于,在这种情况下,您可以直接使用
Task.WhenAll返回的数组,而不是像链接答案中那样单独处理结果。
标签: c# async-await