Асинхронная функция в Vala — доходность и обратный вызов

Я разрабатываю проект, написанный на Vala и GTK+, мне нужно реализовать асинхронную функцию, поэтому я задался целью сделать пример теста... и почему-то получаю следующую ошибку:

async.vala:31.3-31.20: ошибка: доступ к асинхронному обратному вызову `asyncProc.callback' не разрешен в этом контексте asyncProc.callback();

код выглядит следующим образом:

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;
}

и компилируется с помощью следующей команды:

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

У кого-нибудь есть идеи, потому что это может произойти? Проект, который я разрабатываю, выглядит следующим образом: https://launchpad.net/gcleaner


person lozanotux    schedule 12.06.2015    source источник


Ответы (2)


Решение:

Сначала мы объявляем глобальную переменную обратного вызова следующим образом:

public SourceFunc callback;

Затем в асинхронной функции asyncProc добавьте следующую строку:

callback = asyncProc.callback;

Наконец, мы делаем асинхронный обратный вызов из основной функции со следующей строкой:

callback ();

Чтобы проиллюстрировать решение, ниже полный код:

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;
}
person lozanotux    schedule 23.06.2015

Когда вы находитесь внутри обратного вызова, у вас есть доступ к вашему собственному состоянию в качестве делегата с именем asyncProc.callback. Когда вы выходите из этой функции, у вас нет возможности отслеживать это состояние, если вы не поместите его куда-нибудь. Помните, что делегаты в Vala — это замыкания: у них есть функция и информация о состоянии.

Если вы посмотрите на примеры, Generator использует метод feed для хранения значения и состояния где-нибудь (в полях), чтобы позже он мог повторно вызвать обратный вызов. Он не вызывает generate.callback, он вызывает поле callback, которое является просто делегатом.

person apmasell    schedule 12.06.2015
comment
Большое спасибо за ответ. Это не помогает мне решить то, что я пытаюсь сделать. В примерах используйте Yield для вызова асинхронных методов существующих классов. И то, что я хочу сделать, это вернуться туда, где прерывается поток моей асинхронной функции (с Yield ). Но это помогло мне исследовать немного больше, но я все еще не могу решить это! - person lozanotux; 22.06.2015
comment
Вам нужно создать объект для хранения этого состояния, а затем ваш вызывающий код управляет экземплярами этого объекта. Вы также можете поместить это состояние где-нибудь глобально, но это, вероятно, трудно управлять. - person apmasell; 22.06.2015