[Gtk-sharp-list] Thread-safe GUI update

Leon Stringer leon.stringer at ntlworld.com
Fri Mar 23 18:46:57 EDT 2007


Michael Hutchinson wrote:
> 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 

Thanks Michael, that's a fairly comprehensive answer! I'll try adding 
the second queue and play around with the locking...


More information about the Gtk-sharp-list mailing list