【发布时间】:2022-01-15 12:40:16
【问题描述】:
我正在使用库 CsvHelper 来读取与解决方案位于同一位置的文本文件中的一些数据。文本文件有大约 12 000 行,这不算多。 但这需要超过 10 分钟左右的时间,并让页面/浏览器说“此页面没有响应”。
在不使用 Tasks 而是直接在 Main 方法中读取相同文件时,只需不到一秒的时间即可获得相同数量 (12 000) 的记录。 我是否以错误的方式使用任务?
//method within the caller class
private static async Task<IResult> GetEmployees(IEmployeeData data)
{
try
{
return Results.Ok(await data.GetEmployees());
}
catch (Exception ex)
{
return Results.Problem(ex.Message);
}
}
//method within class that implements ICsvDataAccess
public Task<IEnumerable<T>> LoadData<T>(string path, bool hasHeaderRecord = false, string delimiter = ";")
{
return Task.Run(() =>
{
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
HasHeaderRecord = hasHeaderRecord, Delimiter = delimiter
};
using (var reader = new StreamReader(path))
using (var csv = new CsvReader(reader, config))
{
return csv.GetRecords<T>().ToList().AsEnumerable();
}
});
}
//within EmployeeData class which implements IEmployeeData interface
private readonly ICsvDataAccess _file;
public Task<IEnumerable<EmployeeModel>> GetEmployees() =>
_file.LoadData<EmployeeModel>(path: "data.txt");
public interface IEmployeeData
{
Task<IEnumerable<EmployeeModel>> GetEmployees();
}
public interface ICsvDataAccess
{
Task<IEnumerable<T>> LoadData<T>(string path, bool hasHeaderRecord = false, string delimiter = ";");
}
谢谢!
【问题讨论】:
-
您是否已按照说明进行操作?究竟哪条线需要这么长时间?
-
您能否重命名两个
GetEmployees方法之一?目前你的代码 sn-p 很混乱,因为这个名字冲突。 -
附带说明,异步方法by convention 以
Async后缀命名。LoadDataAsync和GetEmployeesAsync是正确的。LoadData方法也违反了 not exposing asynchronous wrappers for synchronous methods 的准则。 -
您是否在所有这些 Task 返回方法中遗漏了很多 async/await?
-
这真的完成了吗?听起来您已经通过将任务排队到不适合他们的 ASP.NET 线程上来击中deadlock。如果您要异步加载 CSV,则不应使用请求线程执行此操作,因为您可能希望向用户返回响应,然后该用户具有加载微调器或等待 CSV 准备就绪的东西,所以我建议检查您正在使用的 .NET Web 框架如何让您使用异步代码。
标签: c# .net task task-parallel-library csvhelper