<p>I'm sure there is a good (or at least decent) reason for this.  What is it?</p>

It is so that you don't have two things trying to update the control at the same time. (This could happen if the CPU switches to the other thread in the middle of a write/read)
Same reason you need to use mutexes (or some other synchronization) when accessing shared variables between multiple threads.
Edit:
In other languages such as C++ you are
  free to try and do this (without an
  exception being thrown as in
  WinForms), but you'll end up learning
  the hard way!
Ahh yes...I switch between C/C++ and C# and therefore was a little more generic then I should've been, sorry... He is correct, you
can
do this in C/C++, but it will come back to bite you!