Desktop Application UI Freezes in Function Call (C#, VB.NET, VB6, Xojo, etc.)
I often get this question: “I’m calling the method XYZ and the UI freezes until the method returns.”.
For example: “I’m trying to upload a file in FTP. I’m trying the examples of the site but the screen remains locked until the end of the upload. It’s very important that while I’m uploading a file in ftp I can continue working with the window.”
The architecture of an interactive desktop application with a UI is a language runtime that runs an event loop. It is single thread. Your application code runs in functions that are called when something happens (a button is pressed, or a menu option chosen, or a keypress or mouse click). Let’s say you have a button that when pressed, calls your application code to upload a file to an FTP server. Let’s say you click that button, and then immediately after you wish to move a scrollbar elsewhere in the UI. You won’t be able to move the scrollbar until after the button press function returns. This is because the UI event loop is a single thread, and control needs to return to the UI thread to allow the “scrollbar move” events to be handled. In most cases, you never notice because your application code does not take very long to run, and control is quickly returned to the runtime’s UI event loop.
For the cases where your application code may take some time, your application’s UI will freeze.
There are a few solutions:
- (In my opinion, this is usually the best choice.) Investigate the thread functionality provided by your programming language. Find out how to start a background thread that runs a function where you can pass arguments to it. Do the time consuming task in the background thread. This allows for control to be returned quickly to the main UI thread, while the background thread can continue with the time consuming task. Become proficient in knowing how to do this. Become knowledgeable in what your programming language offers in terms of thread synchronization, and how to update UI controls from a background thread.
- Use an asynchronous Chilkat method. These are methods that return a Chilkat Task object where Chilkat will run the Chilkat method in a background thread. In my opinion, this is sometimes a good choice, but in the majority of cases the solution above (1) is a much better choice. In other words, creating the background thread yourself and calling the synchronous Chilkat method within your own background thread is simpler, especially if you become proficient in your programming language’s thread API and have developed a set of “building blocks” that you can use over and over.
- Call the Chilkat method synchronously from the main UI thread, but establish a Chilkat AbortCheck event to fire periodically, perhaps ever 1/10th of a second. In your AbortCheck event you can call your programming language’s “DoEvents” method to handle any new UI events. This is usually OK, and in VB6 is it is a typical thing to do. It’s not recommended if you can solve by (1) or (2). There is obviously a reentrancy issue to mull over (although over the years, or decades now.. it seems to be fine in VB6).