Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I think there are many questions in your single post, and I'll try to address them all:</p> <p><strong>Accessing Visual Controls From Other Threads</strong></p> <p>Both Winforms and WPF were build based on the fact that <em>only a single thread can change the object state</em>, and that thread is, of course, the same that created the object.</p> <p>You can imagine why this is important: controls are objects that knows how to "render" or "draw" themselves. While drawing, re-sizing, moving/being dragged, properties of the object cannot be changed from "outside" of the control itself. Of course, the main thread is already busy doing the transformations I mentioned, so its guaranteed that "user" code running on the main thread won't change it. However, another thread running in parallel might do exactly that. Imagine, for example, that the main thread is rendering a text from a <code>TextBox</code> and half the word was written when a second thread changes the text. This would cause problems for the calculation of the width of the text for instance.</p> <p><strong>Using Dispatcher</strong></p> <p>What the thread dispatcher does is * marshal* your code to the main thread. You see, most visual frameworks, WinForms and WPF included, are based on a "application loop". This means that your application in running inside a <code>while(true){}</code> block. Your code (for instance, <code>listViewFiles_SelectionChanged</code>) is called from this loop when its needed. The object that manages this calls is the <code>Dispatcher</code>. It has a <em>queue</em> of stuff to run, and it decides that to run next. When the code the dispatcher called is run, nothing else happens on the visual part of the application -- after all, that is what the thread is doing, right? So it can't process user input, re render the screen, etc.</p> <p>The <code>Dispatcher</code> provides you with an interface that can be called from another thread which <em>posts</em> a new method to be called by the dispatcher, by inserting it on the queue. It's not immediately executed, as you can understand: you are on the second thread calling the main, and the main might be busy either rendering the screen, processing input or even running your code such as <code>listViewFiles_SelectionChanged</code>. Once that loop iteration ends, <code>Dispatcher</code> will check the queue. Depending upon the priority of your method, it might be the next one to be executed or even wait a few more iterations. </p> <p>For this reason, if you stick everything you are doing in the second thread on the dispatcher method, you are effectively asking the framework to run your second thread code on the main thread. And, since your thread code runs forever, the main thread will be forever busy runnning that code (<code>DoWork</code>) and will no longer be able to do anything else.</p> <p><strong>Dispatcher Good Practices</strong></p> <p>So, in conclusion of the above items, when you marshall code to the dispatcher, the main thread gets busy doing it. And while busy, your application becomes <em>unresponsive</em>. Since we want a responsive app all the time, we must do <strong>as little as necessary</strong> on the main thread, that is, on whatever we ask the Dispatcher to marshal. </p> <p>That being the case, what you must do is only marshal <strong>lines</strong> that access Controls. Even if that means many calls to the Dispatcher -- you'll pay a price for that calls, of course, but it's better than stuck the Main Thread with your code longer than necessary.</p> <p><strong>Using a Dispatcher With A Single-Thread</strong></p> <p>The <code>Dispatcher</code> can also help you even if you don't have a second thread. If you need to perform long calculations, you can use a set of flags or a <code>enum</code> to keep track of the state. In the method, you call the dispatcher passing your own method (with a low priority) and them returning (so you break your calculation in parts). </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload