It is working as intended.
It may not be what you expected, but the problem here is your expectations.
What happens when you fiddle with properties on most visual controls, that should end up changing the appearance of the control, is first to make the internal adjustments to the controls properties (ie. data), and then trigger a redraw. To trigger the redraw, a message is usually posted to the message queue of the thread that owns this visual control.
This thread usually processes messages one at a time, be it a button click, mouse movement, or the paint messages that was just posted because you changed the image.
However, that thread is basically written like this (pseudo-code):
while (true)
{
var message = GetNextMessageFromQueue();
ProcessMessage(message);
}
The last time this loop was active, it started processing a message that ended up calling your code, the one that is now sleeping.
So basically, to get the message pump (the typical name of the code that implements this loop) to continue pumping messages, and thus process your paint message, is not to sleep.
You might want to separate your processing out to a different thread, or some other asynchronous way of doing things "in the background".
Note that you will get the same problem if you start doing any kind of lengthy processing in response to a button click or similar, without doing it on a background thread (or again, some other asynchronous way). The GUI will appear to have frozen.
This problem, however, is so common that Microsoft ended up building in special support for it in Windows. It used to be that a window just seemed to hang. Now, however, if the message queue "fills up", Windows will fade out the windows and tack on a caption to it indicating that it has stopped responding. Not a solution, but slightly better.