eric’s extremeboredom

adventures into and out of extreme boredom.

Simplifying Gtk# IdleHandler

One of the problems with using Gtk# is that Gtk/X are not thread safe, meaning you cannot manipulate the GUI from another thread and expect it to work very well.

To get around this, there you can have GLib run methods in the main loop by using GLib.Idle.Add. In windows, Form.Invoke performs the same task, but has one very large advantage over GLib.Idle.Add - it will allow you to use any delegate, while Glib.Idle.Add only takes an IdleHandler, which does not allow you to specify any arguments.

One of the common methods of dealing with this shortfall is creating a class that encapsulates your method and stores the parameters it needs, however having an entire class for every method quickly becomes pretty silly.

Here is a simple class that I hacked up that makes it easy to run any method on the main loop:

public class Example {
	public void Go() {
		/* Let's assume this method was called by another thread */
		RunOnMainThread.Run(this, "DoSomethingToGUI", new object[] { "some happy text!" });
	}
	private void DoSomethingToGUI(string someText) {
		/* Do something to the GUI here */
	}
}

public class RunOnMainThread {
	private object methodClass;
	private string methodName;
	private object[] arguments;

	public static void Run(object methodClass, string methodName, object[] arguments) {
		new RunOnMainThread(methodClass, methodName, arguments);
	}

	public RunOnMainThread(object methodClass, string methodName, object[] arguments) {
		this.methodClass = methodClass;
        this.methodName = methodName;
		this.arguments = arguments;
		GLib.Idle.Add(new IdleHandler(Go));
	}
	private bool Go() {
		methodClass.GetType().InvokeMember(methodName, BindingFlags.Default | BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.InvokeMethod, null,methodClass, arguments);
		return false;
	}
}

Categorized as Technology/Software Development, Technology

1 Comments

  1. Updating the GUI from another thread is NEVER thread safe - even in windows. In windows it might work - but it will throw random General Protection Fault messages at you.

Leave a Reply