You’ll need both. One in the thread code to check to see if threads have been requested to stop (unless the calculation is very short–see below), and also one to stop new thread creation.
The new thread creation loop is probably running on the main thread – same as the UI – so it’s blocking the button press. Put it in a thread of its own to keep the UI responsive.
Note that, if the calculations in the threads are long-running, you’ll want to put the stop check inside the calculation loop, or if there’s not a loop, between steps, if possible. Otherwise, these will continue to run until complete. Putting it at the beginning will have little effect. Your other option here is to keep an array of the threads, and when you stop processing, walk through it calling the Stop() method. I have had some issues with this on Windows, though.
However, if your individual calculations are short, you may want to consider not launching separate threads. Rather, put the whole process in a single thread. You may be incurring more overhead in thread management than time savings. Note that threads aren’t multicore, so running threads is always slower than just executing the processing on the main thread. Threads keep your UI responsive, but you aren’t gaining any performance by breaking the computation into multiple threads as describe; you’ll get the responsive UI with a single thread for the whole job with minimal overhead. If you are looking to distribute the job to multiple cores, you’ll want to use Workers.