I have some c# code (MVC WebAPI) which iterates over an array of IDs in parallel and makes an API call for each entry. In the first version, the whole code was a simple, synchronous for loop. Now we changed that to a combination of Task.WhenAll and a LINQ select:

```
private async Task RunHeavyLoad(IProgress<float> progress) {
  List<MyObj> myElements = new List<MyObj>(someEntries);
  float totalSteps = 1f / myElements.Count();
  int currentStep = 0;

  await Task.WhenAll(myElements.Select(async elem => {
    var result = await SomeHeavyApiCall(elem);
    DoSomethingWithThe(result);
    progress.Report(totalSteps * System.Threading.Interlocked.Increment(ref currentStep) * .1f);
  }

  // Do some more stuff
}

```

This is a simplified version of the original method! The actual method `EnforceImmediateImport` is called by this SignalR hub method:

```
public class ImportStatusHub : Hub {
  public async Task RunUnscheduledImportAsync(DateTime? fromDate, DateTime? toDate) {
    Clients.Others.enableManualImport(false);

    try {
      Progress<float> progress = new Progress<float>((p) => Clients.All.updateProgress(p));
      await MvcApplication.GlobalScheduler.EnforceImmediateImport(progress, fromDate, toDate);

    } catch (Exception ex) {
      Clients.All.importError(ex.Message);
    }

    Clients.Others.enableManualImport(true);
  }
}

```

Now I wonder, if this is "thread safe" per se, or if I need to do something with the `progress.Report` calls to prevent anything from going wrong.