Async Method Samples

These illustrate the use of async methods in Vala. The Vala Tutorial has more details on using async methods. See also GIO Samples which has a couple of examples which use async.

GIO Example

This illustrates calling async methods from within an async method.

async void list_dir () { var dir = File . new_for_path ( Environment . get_home_dir ()); try { var e = yield dir . enumerate_children_async ( FileAttribute . STANDARD_NAME , 0 , Priority . DEFAULT , null ); while ( true ) { var files = yield e . next_files_async ( 10 , Priority . DEFAULT , null ); if ( files == null ) { break ; } foreach ( var info in files ) { print ( " %s

" , info . get_name ()); } } } catch ( Error err ) { warning ( " Error: %s

" , err . message ); } } void main () { var loop = new MainLoop (); list_dir . begin (( obj , res ) => { list_dir . end ( res ); loop . quit (); }); loop . run (); }

Background thread example

This illustrates an async method which starts a background thread to do processing, and receives a result back from it when it is complete. It also illustrates catching exceptions from an async method.

async double do_calc_in_bg ( double val ) throws ThreadError { SourceFunc callback = do_calc_in_bg . callback ; double [] output = new double [ 1 ]; ThreadFunc < bool > run = () => { double result = 0 ; for ( int a = 0 ; a < 100000000 ; a ++) result += val * a ; output [ 0 ] = result ; Idle . add (( owned ) callback ); return true ; }; new Thread < bool >( " thread-example " , run ); yield ; return output [ 0 ]; } void main ( string [] args ) { var loop = new MainLoop (); do_calc_in_bg . begin ( 0.001 , ( obj , res ) => { try { double result = do_calc_in_bg . end ( res ); stderr . printf (@ " Result: $result

" ); } catch ( ThreadError e ) { string msg = e . message ; stderr . printf (@ " Thread error: $msg

" ); } loop . quit (); }); loop . run (); }

Generator example

This is based on Luca Bruno's Generator. It illustrates using async methods to emulate a generator style of iterator coding. Note that this runs fine without a main loop.

abstract class Generator < G > { private bool consumed ; private unowned G value ; private SourceFunc callback ; public Generator () { helper . begin (); } private async void helper () { yield generate (); consumed = true ; } protected abstract async void generate (); protected async void feed ( G value ) { this . value = value ; this . callback = feed . callback ; yield ; } public bool next () { return ! consumed ; } public G get () { var result = value ; callback (); return result ; } public Generator < G > iterator () { return this ; } } class IntGenerator : Generator < int > { protected override async void generate () { for ( int i = 0 ; i < 10 ; i ++) { if ( i % 2 == 0 ) yield feed ( i ); } } } void main ( string [] args ) { var gen = new IntGenerator (); foreach ( var item in gen ) stdout . printf (@ " Result: $item

" ); }

Async sleep example

This is a version of the venerable sleep() function which allows the main loop to continue iterating, and therefore will not block the UI:

public async void nap ( uint interval , int priority = GLib . Priority . DEFAULT ) { GLib . Timeout . add ( interval , () => { nap . callback (); return false ; }, priority ); yield ; } private async void do_stuff () { yield nap ( 1000 ); } private static int main ( string [] args ) { GLib . MainLoop loop = new GLib . MainLoop (); do_stuff . begin (( obj , async_res ) => { loop . quit (); }); loop . run (); return 0 ; }

Simple Example

class Test . Async : GLib . Object { public async string say ( string sentence ) { GLib . Idle . add ( this . say . callback ); yield ; return sentence ; } public static int main ( string [] args ) { Test . Async myasync = new Test . Async (); GLib . MainLoop mainloop = new GLib . MainLoop (); myasync . say . begin ( " helloworld " , ( obj , res ) => { string sentence = myasync . say . end ( res ); print ( " %s

" , sentence ); mainloop . quit (); }); mainloop . run (); return 0 ; } }

Vala/Examples