I am looking for the best way to run a method with multiple threads.
Here is a method I'd like to run
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" });
}
I need to run this method for Id 1 to 40 and currently, it's done by hangfire with 10 jobs.
In 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 * * * *");
This is 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);
}
}
So each jobs handle 4 ids(eg..GenerateAll1 runs for Id 1,11,21 and 31) But I found that this is inefficient. Because when GenerateById(11) takes long, GenerateById(21) and GenerateById(31) won't be running until GenerateById(11) is finished even though GenerateAll2 job is already finished.
What I want to do is that run just 1 job by hangfire like
recurringJobManager.AddOrUpdate(
"GenerateAll1",
() => serviceProvider.GetService<IGenerator>().GenerateAll(), "0 * * * *");
and GeneratAll() method creates 10 threads and each of threads grab Id and run GenerateById method. And when it's done, it runs GenerateById with an id that hasn't been generated. So all 10 threads are working until all data settings are generated.
Can I please get any suggestions on this situation?
Thanks