问题描述
这是我要运行的方法
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个线程都将工作,直到生成所有数据设置为止。
请问有关这种情况的任何建议?
谢谢
解决方法
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" });
}