Async Function in Vala - Yield & Callback

1.7k views Asked by At

I'm developing a project written in Vala and GTK +, I need to implement an asynchronous function, therefore I set out to make an example of test ... and for some reason I get the following error:

async.vala:31.3-31.20: error: Access to async callback `asyncProc.callback' not allowed in this context asyncProc.callback ();

the code is as follows:

using Gtk;

public async void asyncProc ()
{
    stdout.printf ("STEEP -- 1 --\n");

    yield;//Return to Main after the *1

    stdout.printf ("STEEP -- 2 --\n");
}

public static int main (string[] args)
{
    Gtk.init (ref args);

    var win = new Window ();
    win.set_title ("Async Functions Test");
    win.set_default_size (512,100);
    win.set_border_width (12);

    win.destroy.connect (Gtk.main_quit);

    var boton = new Button.with_label ("  Print in Terminal  ");

    //public delegate void AsyncReadyCallback (Object? source_object, AsyncResult res) callback_finalizacion;

    boton.clicked.connect (()=> { 
        asyncProc.begin ();
        //--> Return of YIELD
        stdout.printf ("STEEP -- B --\n");
        asyncProc.callback ();
    });

    win.add (boton);
    win.show_all ();

    Gtk.main ();
    return 0;
}

and compiled using the following command:

valac --pkg gtk+-3.0 --pkg gio-2.0 async.vala

Anyone have any idea because it can happen? The project I'm developing is as follows: https://launchpad.net/gcleaner

2

There are 2 answers

0
lozanotux On BEST ANSWER

The solution is:

First we declare a callback global variable as follows:

public SourceFunc callback;

Then, in the asynchronous function asyncProc add the following line:

callback = asyncProc.callback;

Finally, we make the asynchronous callback from the main function with the following line:

callback ();

To illustrate the solution, below the full code:

using Gtk;

public SourceFunc callback;

public async void asyncProc ()
{
    callback = asyncProc.callback;

    stdout.printf ("STEEP -- 1 --\n");

    yield;//Return to Main after the *1

    stdout.printf ("STEEP -- 2 --\n");
}

public static int main (string[] args)
{
    Gtk.init (ref args);

    var win = new Window ();
    win.set_title ("Async Functions Test");
    win.set_default_size (512,100);
    win.set_border_width (12);

    win.destroy.connect (Gtk.main_quit);

    var boton = new Button.with_label ("  Print in Terminal  ");

    boton.clicked.connect (()=> { 
        asyncProc.begin ();

        //--> Return of YIELD

        stdout.printf ("STEEP -- B --\n");
        callback ();//--> Return just after the last executed yield (... *1)
    });

    win.add (boton);
    win.show_all ();

    Gtk.main ();
    return 0;
}
2
apmasell On

When you are inside the callback, you have access to your own state as a delegate named asyncProc.callback. When you exit out of that function, you have no way of tracking that state unless you put it somewhere. Remember that delegates in Vala are closures: they have a function and state information.

If you look at the examples, the Generator uses the feed method to store the value and state somewhere (in the fields), so that later, it can re-invoke the callback. It's not invoking the generate.callback, it's invoke the callback field, which is just a delegate.