0

So if you try to update GUI controls (datagridviews, checkboxes etc.) from a background thread, you will get an invalid cross-thread operation exception. To update your GUI, you need to return to the main thread and do it from there.

While I like this housekeeping logic, keeping jobs for main and background threads distinctly defined, I'm not sure what problems could be caused (or better said how things could get messed up) if this was allowed. Can someone explain for what reason it was decided to be like this?

Iason
  • 209
  • 3
  • 11
  • 38
  • 1
    Because the methods that update the UI (like painting methods etc.) are not thread safe, so the result will be undefined if they are called from different threads. – René Vogt May 17 '16 at 07:44
  • @RenéVogt You are not correct. We live in the world of non-thread safe objects. We lock them all around and no problem. GUI objects are no exclusion. – Zverev Evgeniy May 17 '16 at 07:45
  • @ZverevEugene if you want to spoil your code with locks around your UI objects, you can do that. But that's not already implemented for you. So, Windows.Forms and the underlying Win32 controls are _not_ thread safe as they are. Therefor you _should_ not use them from different thread ("should" does not mean that you _cannot_ do it if you really want to). – René Vogt May 17 '16 at 07:49
  • Such questions are mostly opinion based. No good for SO. – Zverev Evgeniy May 17 '16 at 07:49
  • @ZverevEugene That's incorrect. One of the main reasons the multitude of GUI systems don't allow updating from worker threads is the extra problems that would cause. Hence GUIs **don't** require any locking –  May 17 '16 at 07:49
  • 1
    This question got marked at a duplicate. Now I don't doubt it has probably been asked before, but it is certainly not a duplicate of the one suggested. This question relates to Win32, C# and .Net and the suggested duplicate relates to Android and Qt. http://stackoverflow.com/questions/11772658/why-is-a-single-threaded-model-used-to-update-the-ui-as-main-thread which is a totally different operating system. – jussij May 17 '16 at 07:50
  • @RenéVogt Why don't you say the same about thousands of other objects you do use from different threads and do lock around? What's the difference between a Dictionary (not thread safe) and a Textbox (not thread safe) from that point of view? – Zverev Evgeniy May 17 '16 at 07:51
  • This question is not a duplicate. The previous questions linked has to do with Android. This is about windows forms. – Iason May 17 '16 at 07:51
  • 1
    Do your research, all these OSs and GUI systems all share the same goal. Read the duplicate link again. The fact that it mentions iOS and Android is irrelevant –  May 17 '16 at 07:53
  • @ZverevEugene This question is not opinion based. There is a correct generally approved way of going about GUI's in windows forms, which is the one in my description. There are also many wrong ways to implement GUI's. – Iason May 17 '16 at 07:54
  • @MickyD indeed. It is about the general principal. See the referenced blog post which mentions some other OSes and their implementation problems with multi-threaded UI. – Patrick Hofman May 17 '16 at 07:58
  • @PatrickHofman Ah excellent, thanks Patrick. :) –  May 17 '16 at 08:00

2 Answers2

1

From here: https://msdn.microsoft.com/en-us/library/ms171728%28v=vs.110%29.aspx

Access to Windows Forms controls is not inherently thread safe.

I suspect that might have a lot to do with this restriction.

But I think the underlying Win32 may also have some restriction on GUIs and threads as it contains functions like PostThreadMessage for sending messages between threads and the Win32 GUI.

jussij
  • 10,370
  • 1
  • 33
  • 49
  • You can use Win32 GUI API from any thread I believe. I used to have fun with multi-threading in VB6 and successfully updated a grid from two threads concurrently. – Zverev Evgeniy May 17 '16 at 07:47
  • For a Win32 GUI the main thread owns the message queue used by that GUI. If you then create a second thread and try to access that queue (i.e. by using SendMessage or PostMessage functions) it can cause a deadlock on that queue. Hence the reason for functions like PostThreadMessage. – jussij May 17 '16 at 07:55
  • 3
    Updating a grid from two threads doesn't really prove it works. You could use UI from multiple threads in earlier .NET versions by mistake, because it didn't really make so many checks on this. And this would work, but only 90% of a time. In other cases generated hard to track errors. – Arek May 17 '16 at 08:01
  • I was not saying "it works" in the meaning it's ok to use it. I was saying there is no hardcoded restriction for this. – Zverev Evgeniy May 17 '16 at 08:20
1

It's probably because Windows Forms controls are actually wrappers for Win32 controls, which have such limitation. Other than that, it is extra hard to make any API safe for multithreading and doesn't really make sense in UI. Think about user dragging a window in one thread, while the other thread is closing it - how to handle it? There would be millions situations like this.

Arek
  • 1,276
  • 1
  • 10
  • 19
  • Win32 controls do not have that limitation. – Zverev Evgeniy May 17 '16 at 07:48
  • @ZverevEugene Well that's because they're not object-orientated not to mention there is a Windows message pump serialising all your WM_SETTEXT messages –  May 17 '16 at 08:04