An application is considered non-responsive when it doesn't pump its message queue. The message queue in Winforms is pumped on the GUI thread. Therefore, to make your application "responsive", you need to make sure the GUI thread has opportunities to pump the message queue - in other words, it must not run your code.
You mentioned that the Thread.Sleep
simulates a "delay" in some operation you're making. However, you need to consider two main causes of such "delays":
- An I/O request waiting for completion (reading a file, querying a database, sending an HTTP request...)
- CPU work
The two have different solutions. If you're dealing with I/O, the best way would usually be to switch over to using asynchronous I/O. This is a breeze with await
:
var response = await new HttpClient().GetAsync("http://www.google.com/");
This ensures that your GUI thread can do its job while your request is pending, and your code will restore back on the UI thread after the response gets back.
The second one is mainly solved with multi-threading. You should be extra careful when using multi-threading, because it adds in many complexities you don't get in a single-threaded model. The simplest way of treating multi-threading properly is by ensuring that you're not accessing any shared state - that's where synchronization becomes necessary. Again, with await
, this is a breeze:
var someData = "Very important data";
var result = await Task.Run(() => RunComplexComputation(someData));
Again, the computation will run outside of your UI thread, but as soon as its completed and the GUI thread is idle again, your code execution will resume back on the UI thread, with the proper result.