【发布时间】:2021-10-03 23:51:38
【问题描述】:
我最近在一次采访中被问到一个问题,这真的让我思考。
我正在努力了解和了解有关多线程、并行性和并发性以及性能的更多信息。
场景是您有一个文件路径列表。文件保存在您的 HDD 或 Blob 存储上。 您已阅读文件并将它们存储在数据库中。你会如何以最优化的方式做到这一点?
以下是我能想到的一些方法:
最简单的方法是遍历列表并按顺序执行此任务。
Foreach(var filePath in filePaths)
{
ProcessFile(filePath);
}
public void ProcessFile(string filePath)
{
var file = readFile(filePath);
storeInDb(file);
}
我能想到的第二种方法可能是创建多个线程:
Foreach(var filePath in filePaths)
{
Thread t = new Thread(ProcessFIle(filePath));
t.Start();
}
(not sure if the above code is correct.)
第三种方式是使用异步等待
List<Tasks> listOfTasks;
Foreach(var filePath in filePaths)
{
var task = ProcessFile(filePath);
listOfTasks.Add(task);
}
Task.WhenAll(listOftasks);
public async void ProcessFile(string filePath)
{
var file = readFile(filePath);
storeInDb(file);
}
第四种方式是并行。对于:
Parallel.For(0,filePaths.Count , new ParallelOptions { MaxDegreeOfParallelism = 10 }, i =>
{
ProcessFile(filePaths[i]);
});
它们之间有什么区别。哪一个更适合这份工作,还有什么更好的吗?
【问题讨论】:
-
您只是将文件本身移动到数据库中,还是解析文件的内容,例如 .csv 并将内容发送到数据库。
-
@DekuDesu 是的,您正在解析文件的内容。
-
你可以看看这个问题:Parallel.ForEach vs Task.Run and Task.WhenAll。它可能会直接回答您的问题。顺便说一句,您在问题中提到的选项都不是最佳选项。仅使用数据并行性不会获得最佳性能。您还需要任务并行性。有一个例子here。
-
您的第三种方式,“异步等待”方法的编码非常糟糕。它实际上并没有使用
await,而async应该是async void,而它应该是async Task。最好运行自己的Task.Run调用,以确保它被推送到后台任务。
标签: c# .net multithreading asp.net-core .net-core