[Gtk-sharp-list] Thread-safe GUI update
Michael Hutchinson
m.j.hutchinson at gmail.com
Thu Mar 22 17:36:02 EDT 2007
On 3/22/07, Leon Stringer <leon.stringer at ntlworld.com> wrote:
> Hi,
>
> I'm updating a list (TreeView with TreeStore) from a thread when
> processing some items, something like:
>
> while (Messages.Count > 0) {
> msg = (Message) Messages.Dequeue();
> send(msg);
>
> Gtk.Application.Invoke(delegate {
> treeStore.AppendAvalues(msg.To, msg.Text);
> });
>
> Thread.Sleep(0);
> }
>
> There's another thread adding messages to the message queue.
>
> The problem is that sometimes the Gtk.Application.Invoke() is executed
> after I've dequeued the next message so the wrong item is added to the
> list. I could stick a greater value in Thread.Sleep() but this would be
> a kludge. Is there any thread-safe way to do this?
The problem lies in using an anonymous delegate. The compiler compiles
the anonymous delegate to a private method, which gets access to
variables in the "parent" method's scope via a private shared object
in the parent class. Your code is changing the shared variables before
Gtk.Application.Invoke gets fired.
However, it may be possible to do it with Gtk.Application.Invoke
(object sender, System.EventArgs args, System.EventHandler d).
Alternatively you could create a queue object at the class level and
put the messages in that. You'd need to lock it (on the SyncRoot
property) when you add and remove objects, or you could use the build
in sychronisation wrapper to make it thread safe:
http://msdn2.microsoft.com/en-gb/library/system.collections.queue.issynchronized.aspx
--
Michael Hutchinson
http://mjhutchinson.com
More information about the Gtk-sharp-list
mailing list