简体   繁体   中英

Cancel background running jobs in Parallel.foreach

I have a parallel foreach for few api calls. Api will return some data and I can process it. Lets say from front end, I call to ProcessInsu method and suddenly the user change his mind and go to other page. (There should be a clear button and user can exit the page after clicking clear button.) After calling ProcessInsu method, it will run APIs in background. It is waste of resources because, the user already change his mind and do other work. I need some methodology to cancel background running jobs.

public async Task ProcessInsu(InsuranceAccounts insuranceCompAccounts,string resourceId)
{
     ParallelOptions parallelOptions = new ParallelOptions();
     parallelOptions.MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling((Environment.ProcessorCount * 0.75) * 2.0));

     Parallel.ForEach(insuranceCompAccounts, parallelOptions, async (insuranceComp) =>
    {
        await Processor.Process(resourceId,insuranceComp); //When looping, From each call, it will call to different different insurance companies.              
    });

} 

I tried this sample code and I could not do my work with that. Any expert can guide me to do this?

As others have noted, you can't use async with Parallel - it won't work correctly. Instead, you want to do asynchronous concurrency as such:

public async Task ProcessInsu(InsuranceAccounts insuranceCompAccounts, string resourceId)
{
  var tasks = insuranceCompAccounts.Select(async (insuranceComp) =>
  {
    await Processor.Process(resourceId, insuranceComp);
  }).ToList();
  await Task.WhenAll(tasks);
}

Now that the code is corrected, you can add cancellation support. Eg:

public async Task ProcessInsu(InsuranceAccounts insuranceCompAccounts, string resourceId)
{
  var cts = new CancellationTokenSource();

  var tasks = insuranceCompAccounts.Select(async (insuranceComp) =>
  {
    await Processor.Process(resourceId, insuranceComp, cts.Token);
  }).ToList();
  await Task.WhenAll(tasks);
}

When you are ready to cancel the operation, call cts.Cancel(); .

Note that Process now takes a CancellationToken . It should pass this token on to whatever I/O APIs it's using.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM