【发布时间】:2021-02-21 01:41:10
【问题描述】:
我正在寻找使用多线程运行方法的最佳方式。
这是我想运行的方法
public async Task<IActionResult> GenerateById(int id)
{
//make a web request and save response to database using EF.
return Json(new { success = true, message = "Worked" });
}
我需要为 ID 1 到 40 运行此方法,目前,它由 hangfire 完成,有 10 个作业。
在startup.cs中
recurringJobManager.AddOrUpdate("GenerateAll1",
() => serviceProvider.GetService<IGenerator>().GenerateAll(1), "0 * * * *");
recurringJobManager.AddOrUpdate("GenerateAll2",
() => serviceProvider.GetService<IGenerator>().GenerateAll(2), "0 * * * *");
recurringJobManager.AddOrUpdate("GenerateAll3",
() => serviceProvider.GetService<IGenerator>().GenerateAll(3), "0 * * * *");
....
recurringJobManager.AddOrUpdate("GenerateAll10",
() => serviceProvider.GetService<IGenerator>().GenerateAll(10), "0 * * * *");
这是GenerateAll
public async Task GenerateAll(int mod)
{
if (mod == 10)
{
mod = 0;
}
List<DataSetting> listsToUpdate = _unitOfWork.DataSetting.GetAll(r => r.Id%10 == mod ).ToList();
foreach (var list in listsToUpdate )
{
await GenerateById(list.Id);
}
}
所以每个作业处理 4 个 id(例如 ..GenerateAll1 为 Id 1、11、21 和 31 运行) 但我发现这是低效的。 因为当 GenerateById(11) 需要很长时间时,即使 GenerateAll2 作业已经完成,GenerateById(21) 和 GenerateById(31) 也不会运行,直到 GenerateById(11) 完成。
我想做的是像hangfire一样只运行1个工作
recurringJobManager.AddOrUpdate(
"GenerateAll1",
() => serviceProvider.GetService<IGenerator>().GenerateAll(), "0 * * * *");
GeneratAll() 方法创建 10 个线程,每个线程获取 Id 并运行 GenerateById 方法。 完成后,它会使用尚未生成的 id 运行 GenerateById。 所以所有 10 个线程都在工作,直到生成所有数据设置。
我可以就这种情况获得任何建议吗?
谢谢
【问题讨论】:
-
为什么不为每个 id 创建一个
Task,一次启动它们,然后只使用await整个集合?我想,这里没必要乱搞线程。 -
像
Parallel.For(0, 40, x => GenerateById(x));这样的东西有用吗? -
OP 需要提供更多信息。这是在 Asp.net 应用程序上吗?每个请求是否需要调用 `GenerateById(int id)` 40 次?等
标签: c# multithreading asynchronous task hangfire