On Thu, 2011-09-29 at 00:25 -0300, Leonardo Ferreira Fontenelle wrote:
I'm trying to port a small Python GTK+ application to Vala. Overall, I have succeeded, with some very interesting performance gains. But in some cases the search may take a few seconds to finish, while the application reads data from the disk. I tried using an async method to keep the user interface responsive, but it didn't work: until the search is completed, the user can't even move the cursor in the text entry widget. What am I missing? This is the relevant code; I hope the names are sufficiently descriptive. public void on_search_entry_activate (Gtk.Entry entry) { this.timer.start(); this.search_progressbar.show(); this.search_treeview.set_model(null); this.search_results.clear(); // this is a Gtk.ListStore string entry_text = entry.get_text(); stdout.printf("Searching for: %s\n", entry_text); string[] words = this.word_regex.split(entry_text); this.search.begin(words, (obj, res) => { this.search.end(res); this.search_treeview.set_model(this.search_results); this.timer.stop(); stdout.printf("%fs elapsed\n", this.timer.elapsed()); this.search_progressbar.hide(); this.search_progressbar.set_fraction(0.0); }); } public async void search (string[] words) { Gee.TreeSet<int32> matches = get_matches (words); string code, title, inclusion_notes, exclusion_notes; //user-relevant data Gtk.TreeIter iter; double fraction = 0.0; double increment = 1.0 / matches.size;
int i count = 0;
foreach (int32 match in matches) { get_node(match, out code, out title, out inclusion_notes, out exclusion_notes);
Probably: yield get_node(match, out code, out title, out inclusion_notes, out exclusion_notes);
this.search_results.append(out iter); this.search_results.set(iter, 0, match, 1, code, 2, title); fraction += increment; this.search_progressbar.set_fraction(fraction);
If get_node cannot be simply yielded: if ((++count % 1024) == 0) { yield; }
} } Thanks in advance, Leonardo Fontenelle
The problem is that by marking method async you move computation to different part of code (in fact IIRC the returning of result in this case) but not splitting it. To get the speedout you should: - yield all I/O actions - split long computations by yield Alternatively you can use threads but: - Threads are move heavyweight as they are system threads - Threads use real parallelism. It means that you can take advantage of multi-core CPU - But IIRC the GDK/GTK+ is not thread-safe by default. You need to add an additional calls to make it safe Regards
Attachment:
signature.asc
Description: This is a digitally signed message part