From: Axel Simon <Axel.Simon@in.tum.de>
On Nov 24, 2010, at 15:11, Herng Yi Cheng wrote:
> The other problem concerns progress bars. I have to do a certain
> computation (in a new thread) that produces a 2D geometrical figure
> that I display in a drawingArea using Cairo. At each stage in the
> computation, I record the current progress in an IORef. Through a
> timeoutAdd I also regularly check the IORef (in the main thread) and
> update the progress bar accordingly using progressBarSetFraction.
> However, when I run the computation, the entire GUI becomes
> unresponsive and static, including the progress bar; after the
> computation is done, the progress bar simply jumps from 0% to 100%.
> To debug, I called "printfraction" below every call to
> progressBarSetFraction to check if my updates were spread evenly
> throughout the computation, and indeed they were. It seems that the
> computation tried to update the progress bar at the right times, but
> the GUI lagged because of the computation; at the end of the
> computation, all the updates were then made in a flurry, so the
> progress bar jumped to 100%. It doesn't even work when I compile
> into an executable. It works, though, if I compile using the -
> threaded flag.
> I don't think I've been doing it correctly because there should be
> some way to do it without compiling specially (or so I think). I
> can't find sample code for progress bar usage too...
There's an example in the demo directory of the gtk package. Please
see the source ball.
How do you handle the update to the GUI? Your second thread needs to
pass the current Cairo context to the GUI thread. Probably by
postGUIAsync or something like that (see Graphics.UI.Gtk.General). You
should update an IORef with the current Cairo Context and then post an
widgetRedraw or so to the widget.
This probably won't directly affect your problem, but if you need to communicate between threads you should use an MVar instead of an IORef. MVar's properly handle locking etc., whereas IORef's are not thread-safe.