There are several reasons why your parallel code is slower. Let's keep in mind the main reason to use parallel threads: You have tasks that are CPU-bound and wish to divide the workload.
The problem is that your code is NOT CPU-bound in the first place. A simple loop over 100_000 iterations is not hogging the CPU. About 8 years ago, using a 3.0 GHz CPU, I found that I could go through 600_000 iterations before parallel threads would be beneficial.
Next, BitArray is a horrible example for using Parallel.For iterating 1 index at a time? As mentioned in a comment, it is not thread-safe but what I want to point out is that a BitArray is backed by a list of integers. So an individual bit in the BitArray maps to a bit on an integer. And with Parallel.For, your loop may be attempting to set individual bits belonging to the same backing integer, which causes many performance issues. Yikes!
A better example would be try using a bool[]. There would be less performance conflicts. Even still, do not expect this to perform better than a simple serial loop.
What could be done to create a loop that rivals or surpasses a serial performance? Besides using a bool[], you should try to increase the array length to half a million or more. But you will still find Parallel.For is slower.
Why? Because Parallel.For creates a new task for each index. Granted, creating a task is a relatively low-impact call but when you create 100K up to 1 million, then a lot of those little impact things add up to a big impact. You could still use parallel threads but the focus should be to create just a few, and not 100K.
You can investiage using a Range Partitioner. Or you can simple create your own chunks based on the array length. A general rule of thumb I apply is to use twice the number of CPU's. That is 2 * Environment.ProcessorCount. Divide the array length by that value to produce a range size. If it does not divide evenly, i.e. has a remainder, then add 1 to the range size. Now just create your own ranges based on that range size.
You can then process each range in parallel. Instead of creating 100K threads, you have created a much smaller amount so you have minimized the overhead of creating tasks.
If you still insist on using BitArray, then the challenge is to produce a range size that is also evenly divided by 32. Why? Because that why a backing intger will belong to only one range. While you process the many ranges in parallel, you still process a given range serially. Since the backing integer would belong to only 1 range, you do not encounter performance conflicts.
Below is a link to a Paritioner class:
https://learn.microsoft.com/en-us/dotnet/api/system.collections.concurrent.partitioner?view=net-8.0