|
-
May 3rd, 2016, 10:13 AM
#2
Re: Windows Forms User Interface freezing for no apparent reason
Every Windows developer /has/ to learn about multithreading. Ideally, in a tame environment without a deadline. It sounds like you're going to have to learn as you go.
There is 1 legal thread from which controls can be accessed. It's called the "Main thread" or the "UI thread". That is also the thread that has to pain the controls. There is a data structure called a "message queue". When anything happens: mouse movements, key presses, repaints, a data structure describing that event ("a message") is placed in the queue. The UI thread loops, checking the queue and processing the messages in order. It looks like multithreading, but it's not.
Say you click a button that changes a TextBox's value. The click puts a message in the queue. The next time the UI thread loops, it sees the click message, removes it from the queue, and executes the button's event handler. That event handler changes the TextBox's text, which puts 2 new messages in the queue: TextChanged and "the textbox needs to paint again". Then the button event handler finishes. The UI thread loops again, and finds the TextChanged event. If there's an event handler, it's executed, and it might add more to the queue. Then the UI thread loops again and finds the "TextBox needs to be painted" event, and lets it repaint. This all happens so fast you think it's instantaneous.
Now imagine the button click handler changes the text, but takes 15 seconds to execute. When the text changes, TextChanged and "I need to paint" still go in the queue. But the button handler is still executing, so the UI thread's still busy. So the text can't change for at least 15 seconds.
The only way to get around this is to try and set up long-running tasks so they run on different threads. That leaves the UI thread free to process the message queue and respond quickly to user input and property changes. I like the Task API for this, lately. But a lot of people feel more comfortable with the BackgroundWorker API. I'm going to type up a crash course in either really quickly, but want to leave this here so you can hear the best instructions:
Go read about the BackgroundWorker class. Go play with the MSDN examples. Try to rewrite them without looking. Get comfortable with thinking about other threads. Don't try to do everything at once, yet. Learn this pattern:
- Gather the information the thread needs.
- Start the thread, using only variables that thread can access.
- Wait for the thread to finish and rejoin the main thread.
- Update controls and get ready to start the next thread.
It's much harder to try and coordinate many threads at once. You're already doing things one at a time. So let's stick with that, because it's easier.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|