我正在寻找运行具有多个线程的方法的最佳方法。
这是我要运行的方法
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)花很长时间时,即使GenerateGeneb2作业已经完成,GenerateById(21)和GenerateById(31)也要等到GenerateById(11)完成后才能运行。
我想做的是像hangfire这样仅执行一项工作
recurringJobManager.AddOrUpdate(
"GenerateAll1",
() => serviceProvider.GetService<IGenerator>().GenerateAll(), "0 * * * *");
和GeneratAll()方法创建10个线程,每个线程都获取Id并运行GenerateById方法。 完成后,它将使用尚未生成的ID运行GenerateById。 因此,所有10个线程都将工作,直到生成所有数据设置为止。
请问有关这种情况的任何建议?
谢谢
答案 0 :(得分:1)
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" });
}