[Gtk-sharp-list] yet another multithreading problem

ub boo@youfuckingbitch.com
Fri, 24 Sep 2004 11:04:39 +0200


hi list!
i am trying to write an application which downloads articles from 
usenet. the problem is, i dont get the download threads to work 
properly. on_download_clicked i start a new thread which connects to a 
usenetserver and downloads queued articles, and another thread which 
loops infintely while downloading, monitors the progess and sends 
information to the gui (updating the progressbar), but the app always 
locks with something like: "Xlib: unexpected async reply (sequence 0x196a)!"
here's what i tried:

public class GladeApp
{
    public static void Main(string[]args)
    {
        new GladeApp(args);
    }

    public static ThreadNotify notify;

    public GladeApp (string[] args)
    {
        Gdk.Threads.Init();
        Application.Init();

        //lots of gui-stuff here [...]

        notify = new ThreadNotify (new ReadyEvent (ready));
      
        Gdk.Threads.Enter();
        Application.Run();
        Gdk.Threads.Leave();
    }

    static void ready()
    {
        filebar.Fraction = Traffic.snapshot;  //get the current fraction 
from traffic class
    }

    public void on_download_clicked (object o, EventArgs e)
    {
        MainClass.Download();
    }
}


public class MainClass  
{
    public static void Download()
    {  
        NNTP nntp1 = new NNTP(files);
        myThread = new Thread(new ThreadStart(nntp1.Start));
        Traffic.downloading=true;
        myThread.Start();
        Thread monitor = new Thread(new 
ThreadStart(Traffic.monitorTraffic));
        monitor.Start();
    }
}


public class Traffic
{
    public static double current = 0; //this gets updated from within 
NNTP class
    public static double snapshot;

    //some methods to calculate fraction from filesize[...]

    public static void monitorTraffic()
    {
        while (downloading){
            Thread.Sleep(1000); //update the gui every second
            snapshot = current;
            Gdk.Threads.Enter();
            GladeApp.notify.WakeupMain();
            Gdk.Threads.Leave();
        }
    }
}
   
thats it. i tried with and without the Gdk.Threads* stuff. it works fine 
for a while, progressbar is updating, then the gui starts locking up (i 
can get it back by pressing some button or opening a menu in the menubar 
- is there something that can be done about this?  
http://www.gtk.org/faq/#AEN492 says i should use gdk_flush(), but i 
can't find an equivalent gtk#-method, i tried "while 
(Application.EventsPending ()) Application.RunIteration ();" instead, 
which seems to do what i want judging from the comments in the monodoc 
sample code, but it instantly locks up the gui).
anyway, playing around with the buttons/menus keeps the gui responsive 
for a while, but then it totaly  locks up with the Xlib async reply error.
i also tried to update the progressbar without the monitor thread, using 
Gtk.Timeout instead of ThreadNotify:

in GladeApp Class
[...]
public void on_download_clicked (object o, EventArgs e)
{
    Traffic.downloading = true;
    Gtk.Timeout.Add (500, new Gtk.Function (Monitor));
    MainClass.Download();
}

bool Monitor()
{
    if (!Traffic.downloading)
    {
        return false;
    }
            
    progressbar1.Fraction=Traffic.current;
    return true;
}

but again xlib async reply error, i am really out of ideas...
thanks in advance
Ulrich