c# - 通过多线程(任务)运行方法的有效方法
问题描述
我正在寻找运行具有多个线程的方法的最佳方法。
这是我想运行的方法
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 个作业。
在启动.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 个线程都在工作,直到生成所有数据设置。
我可以就这种情况获得任何建议吗?
谢谢
解决方案
Parallel.For
对您正在尝试做的事情很有用。目前尚不清楚您对结果的意图是什么GenerateById()
,所以我将把它留给您自己弄清楚。
从文档:
执行一个 for 循环,其中迭代可以并行运行。
recurringJobManager.AddOrUpdate(
"GenerateAll1",
() => serviceProvider.GetService<IGenerator>().GenerateAll(), "0 * * * *");
public async Task GenerateAll()
{
Parallel.For(0, _unitOfWork.DataSetting.Length,
new ParallelOptions() { MaxDegreeOfParallelism = 10 },
x => GenerateById(_unitOfWork.DataSetting[x]).Result());
}
public async Task<IActionResult> GenerateById(int id)
{
...
return Json(new { success = true, message = "Worked" });
}
推荐阅读
- android - 如何从android中的视频中获取当前帧号?
- scala - 在 Scala 中映射和折叠集合
- sql-server - SQL Server 中最耗时的查询计数
- php - curl 命令有效,但 guzzle 失败
- javascript - 输入有效 URL 并重试:Salesforce Lightning Web 组件错误
- go - 选择块如何等待 ctx.Done() 操作?
- java - PowerMock/JUnit/Guice - 用注入模拟私有构造
- c# - WPF 如何取消用户在组合框中的选择?
- iis - LEGACY EDGE ONLY:HTTP 请求未经客户端身份验证方案“协商”的授权。。
- java - 从线程调用类的方法时是否存在并发问题的可能性?