.NET Controls: Why aren't all calls thread safe?

After the explosion with excitement , learning about how to make thread-safe calls in Windows Form Controls, I became interested ...

Why aren't all calls in Windows Form Controls thread safe? Can someone explain why? I would think that this will reduce the mass of confusion for users of these controls.

+4
source share
4 answers

The problem here is not thread safety. All methods are "thread safe" because they do not damage the state of the application when called on several threads at the same time - this is that thread safety includes the exception of the wrong thread (I don’t remember what it's called).

What they have is an afinity thread - they can only be called in one thread, sometimes called a user interface thread, although this is misleading because it means there is only one. This is mainly due to the fact that the OS calls on which they depend have the same flow binding rules.

Believe me, that’s good. When you think about the main role of UI Thread, everything starts to become clear. The task of user interface flows is to receive input from users ’hands, using the keyboard or mouse, act on it and produce output in the form of pixels in response. There is only one user, and this user has only one set of eyes. The user expects to see everything they do on the screen, and most importantly, they expect it to happen in the order in which they did it. A multi-threaded user interface will make this very difficult to achieve - almost impossible.

The problem is that when you mix workflow threads with the user interface thread, you need to make a certain amount to talk to the user interface because you have to be in the user interface thread to do this. Again, as I said, this is good. Someone must do this, otherwise the user will see that everything is happening in the wrong order, and this is bad. The system can, admittedly, do it for you, as well as in some WIN32 calls, but it has problems. First of all, the system cannot know what granularity you need for sorting, so you may be ineffective. Your operations can be better distributed at a higher level than the system can understand. Secondly, marshalling is expensive, and it punishes developers who do the right thing and correctly port everything to the user interface. Thus, the system does everything possible, checks whether it is in the correct thread, and if not, throw an exception.

+8
source

Since this will reduce performance and writing lock-free, thread - safe code is still an area of ​​active research.

+5
source

The actual problem is that Windows forms use their own resources, such as GDI objects, to render forms / controls.

These GDI resources can only be used from the thread that created them, most likely the main thread.

Thus, any form / control call that gui needs to update and thus redraw using GDI resources must be made in the main thread.

Thus, incoming calls from other threads that want to do this must be distributed across the main thread. I am not quite sure how this works behind the scenes, but I assume that this can be done by sending messages to the wnd proc of the form / component. as soon as the main thread processes this message in wndproc, it can call a valid code. And that would be a very expensive way.

+3
source

To expand Darin's answer:

In most cases, Windows Form controls do not have to be thread safe, as they are usually accessible from the user interface thread.

Sometimes they do (for example, in your code).

Thus, adding a stream verification code will add an unacceptable overhead of 95% + of those cases when it is not needed.

+2
source

Source: https://habr.com/ru/post/1309266/


All Articles