Process bunches of records in seperate threads and wait for them all to finish
So your original approach looked something like this:

recordIds.AsParallel()
    .WithDegreeOfParallelism(...)
    .ForAll(id =&gt; SetOwner(id));


which involved a separate call to SetOwner for each record. Because SetOwner has a lot of overhead per call, it's indeed much better to let it operate on batches rather than individual items. But you don't need to use threads for that directly:

recordIds
    .SplitIntoBatches(Settings.Default.WorkerThreads)
    .AsParallel()
    .WithDegreeOfParallelism(Settings.Default.WorkerThreads)
    .ForAll(batch =&gt; SetOwner(batch));


public static IEnumerable&lt;IEnumerable&lt;T&gt;&gt; SplitIntoBatches&lt;T&gt;(this IEnumerable&lt;T&gt; items, int numberOfBatches)
{
    var batchSize = (items.Count() + numberOfBatches - 1) / numberOfBatches;
    for (int i = 0; i &lt; numberOfBatches; i++)
        yield return items.Skip(i * batchSize).Take(batchSize);
}