[MonoDevelop] Issues with the gui thread
Lluis Sanchez
lluis@ximian.com
Mon, 20 Sep 2004 23:58:14 +0200
Hi!
One of the problems I find when writing code for MonoDevelop is that the
user interface can only be modified from the GUI thread. This means
that, for example, if I have a background thread that needs to add
something in the task pane, I need to do it through the DispatchService.
However, the fact that TaskService.AddTask (and many other methods)
needs to run in the gui thread is common knowledge not documented
anywhere, and even if it was documented, this information wouldn't be
reliable. For example, the TaskService itself does not modify the user
interface, but an OpenTaskView object is subscribed to the TaskAdded
event, and that one changes de UI. This makes the development of plugins
really hard.
In order to simplify the development and to make MonoDevelop more stable
I think we should stablish a policy like "any public class that can be
used by a plugin must be gui-thread safe" that is, no matter from which
thread a method is called, it should do its work, internally dispatching
the call through the DispatchService if needed.
Following this rule, the TaskService.AddTask method would not need to do
anything special, since it does not directly modify the gui, but
OpenTaskView would need to internally dispatch the TaskAdded event
through the DispatchService.
To simplify even more the development I propose to build two artifacts:
* Provide a base class for classes that need access to the GUI.
All method calls to objects of that class would be automatically
marshalled and executed in the gui thread. This can be
implemented using ContextBoundObject and the interception sinks
it provides. This would be really useful for example to make the
status bar service thread safe by only changing the base class.
* Provide a method for building wrapper delegates that would
automatically marshall calls into the gui thread, so I could do
something like:
taskService.TasksChanged +=
(EventHandler)DispatchService.CreateGuiDispatch (new
EventHandler (ShowResults));
This would generate a wrapper delegate that would queue the call
into the gui thread. This would need some Reflection.Emit, but
not too much.
Of course, we could still use the traditional DispatchService methods,
but I think that those "artifacts" would be enough for most of
situations.
Any opinions about this?
Lluis.