views:

438

answers:

7

I don't want multiple windows, each with its own UI thread, nor events raised on a single UI thread, not background workers and notifications, none of that Invoke, BeginInvoke stuff either.

  • I'm interested in a platform that allows multiple threads to update the same window in a safe manner. Something like first thread creates three buttons, the second thread another five, and they both can access them,change their properties and delete them without any unwanted consequences.
  • I want safe multi-threaded access to the UI without Invoking, a platform where the UI objects can be accessed directly from any thread without raising errors like "The object can only be accessed from the thread that created it". To let me do the synchronizing if I have to, not prevent me from cross-tread accessing the UI in a direct manner.
A: 

Based on my guessing of your requirement, you want a single Windows Form and having ways to execute certain routines asynchronously (like multi-threading), yes?

Typically (for the case of .NET WinForms) Control.Invoke / Control.BeginInvoke is used to a certain effect what I think you want.

Here's an interesting article which might help: http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

o.k.w
I've updated the question to better reflect the idea. I want safe multi-threaded access to the UI without Invoking, a platform where the UI objects can be accessed directly from any thread without raising errors like "The object can only be accessed from the thread that created it". To let me do the synchronizing if I have to, not prevent me from cross-tread accessing the UI in a direct manner.
luvieere
+3  A: 

I don't believe a platform like that exists per se

There is nothing stopping you from saying taking .Net and creating all new controls which are thread safe and can work like that(or maybe just the subset of what you need) which shouldn't be an extremely large job(though definitely no small job) because you can just derive from the base controls and override any thread-unsafe methods or properties.

The real question though is why? It would definitely be slower because of all the locking. Say your in one thread that is doing something with the UI, well it has to lock the window it's working on else it could be changed without it knowing by the other thread. So with all the locking, you will spend most of your drawing time and such waiting on locks and (expensive) context switches from threads. You could maybe make it async, but that just doesn't seem safe(and probably isn't) because controls that you supposedly just created may or may not exist and would be about like

Panel p=new Panel();
Button b=new Button();
WaitForControlsCreated(); //waits until the current control queue is cleared
p.Controls.Add(b);

which is probably just as slow..

So the real question here is why? The only "good" way of doing it is just having an invoke abstracted away so that it appears you can add controls from a non-UI thread.

I think you are misunderstanding how threads really work and what it takes to actually make an object thread safe

Earlz
"taking .Net and creating all new controls which are thread safe"... What is stopping me is the inability to have more than one UI thread, and to put buttons on the interface directly from, say, a BackgroundWorker.
luvieere
Ok, well if your feeling ambitious, I know that SDL allows multiple threads to draw on a framebuffer(probably possible to get multi threaded event handling going somehow even). I wouldn't recommend creating your own controls for the faint of heart though.
Earlz
"AWT 1.0" (Ohh... the deadlocks didn't happen *all* the time!)
pst
The fact that deadlocks happen at any time still would scare me away from it
Earlz
+2  A: 

You could make a thread-safe Producer/Consumer queue of delegates. Any thread that wants to update a UI component would create a delegate encapsulating the operations to be performed, and add it to the qeueue. The UI thread (assuming all components were created on the same thread) would then periodically pull an item from the queue, and execute the delegate.

mbeckish
I don't want a single "UI Thread", I want a platform where any thread is an UI thread, every thread I create could directly update the interface.
luvieere
Then make a queue per UI thread. That way, other threads are free to put items in the queue without worrying about concurrency, and each UI thread can fail separately without affecting the others.
mbeckish
It's an interesting idea, perhaps the platform I'm looking for would implement all these queues in the background, hidden from the programmer, so I would still keep the same syntax when updating the UI from any of my threads, without being actively aware that my UI update calls are being queued. Edit your answer a bit, so I can remove the downvote, the multiple queue implementation actually helped me directing my searches towards something more specific. Thanks!
luvieere
+1: one UI thread doing the UI calls, and a message passing system via queues to send update commands from the worker threads to the UI thread, and control state back the other way, looks like the way to go to me.
Wim
I do something similar and it can be expanded a lot to make it very easy to communicate back to the UI.
PetriW
+6  A: 

I'm gonna get down voted but ... Go Go Gadget Soapbox.

Multi threaded GUI are not possible in the general case. It has been attempted time and time again and it never comes out well. It is not a coincidence that all of the major windowing frameworks follow the single threaded ui model. They weren't copying each other, it's just that the constraints of the problem lead them to the same answer. Many people smarter than you or i have tried to solve this.

It might be possible to implement a multi-thread ui for a particular project. I'm only saying that it can't be done in the general case. That means it's unlikely you'll find a framework to do what you want.

The gist of the problem is this. Envision the gui components as a chain (in reality it's more like a tree, but a chain is simple to describe). The button connects to the frame, connects to the box, connects to the window. There are two source of events for a gui the system/OS and the user. The system/OS event originate at the bottom of the chain (the windowing system), the user event originate at the top of the chain (the button). Both of these events must move through the gui chain. If two threads are pushing these events simultaneously they must be mutex protected. However, there is no known algorithm for concurrently traversing a double linked list in both directions. It is prone to dead lock. GUI experts tried and tried to figure out ways to get around the deadlocking problem, and eventually arrived at the solution we use today called Model/View/Controller, aka one thread runs the UI.

caspin
I don't want a general case where this would be standard and safe, I want a platform where it would be *allowed*.
luvieere
Good reply Caspin.
PetriW
+1 for the Inspector Gadget reference - and the concise explanation :)
George Shore
A: 

BeOS / Haiku OS

Bryan Batchelder
A: 

On Windows, Window handles have thread affinity. This is a limitation of the Window manager. It's a bad idea to have multiple threads accessing the same window on Windows.

Aaron Klotz
A: 

Accept that any code updating the GUI has to be on the GUI thread. Learn to use BeginInvoke().

Mr Private