Short answer: Very.
Longer answer: Electronic (transistor-based) computers are fast approaching the physical limits of the technology. It is becoming harder and harder to squeeze more clocks out of each core while managing heat generation and the quantum effects of microscopic circuits (circuit paths are already being placed so close together on modern chips that an effect called "quantum tunneling" can make an electron "jump the tracks" from one circuit to another, without needing the proper conditions for a traditional electrical arc); so, virtually all chip manufacturers are instead focusing on making each clock able to do more, by putting more "execution units" into each CPU. Then, instead of the computer doing just one thing per clock, it can do 2, or 4, or even 8. Intel has "HyperThreading", which basically splits one CPU core into two logical processors (with some limitations). Virtually all manufacturers are putting at least two separate CPU cores into one CPU chip, and the current gold standard for desktop CPUs is four cores per chip. Eight is possible when two CPU chips are used, there are server mainboards designed for "quad quad-core" processors (16 EUs plus optional HT), and the next generation of CPUs is likely to have six or eight per chip.
The upshot of all of this is that, to take full advantage of the way computers are gaining computing power, you must be able to allow the computer to "divide and conquer" your program. Managed languages have at least a GC thread which handles memory management separately from your program. Some also have "transition" threads which handle COM/OLE interop (as much for protecting the managed "sandbox" as for performance). Beyond that, though, you really have to start thinking about how your program can do multiple things simultaneously, and architect your program with features designed to allow pieces of the program to be handled asynchronously. Windows, and windows users, will practically expect your program to perform long, complicated tasks in background threads, which keep the UI of your program (which runs in the program's main thread) "responsive" to the Windows message loop. Obviously, problems that have parallelizable solutions (like sorting) are natural candidates, but there are a finite number of types of problems that benefit from parallelization.