2012-05-28 43 views
2

我想執行異步文件IO操作。下面是我試圖在瓦拉做一個簡化版本:在GIO中,爲什麼這些異步文件IO操作從未完成? (適用於C和Vala)

void main(string[] args) { 
    store_async(); 

    while(true) 
     ; 
} 

async void store_async() { 
    File file = File.new_for_path("settings.ini"); 

    stderr.printf("Checking if file exists...\n"); 
    if (!file.query_exists()) { 
     stderr.printf("About to yield file.create_async...\n"); 
     try { 
      yield file.create_async(FileCreateFlags.REPLACE_DESTINATION); 
     } catch (Error err) { 
      error("Error creating file: %s\n", err.message); 
     } 
     stderr.printf("Returned from file.create_async.\n"); 
    } 

    string data = "hello\n"; 
    string new_etag; 
    stderr.printf("About to yield file.replace_contents_async...\n"); 
    try { 
     yield file.replace_contents_async(
      data.data, 
      null, 
      false, 
      FileCreateFlags.NONE, 
      null, 
      out new_etag); 
    } catch (Error err) { 
     error("Error replacing contents: %s\n", err.message); 
    } 

    stderr.printf("Returned from file.replace_contents_async.\n"); 
} 

當我運行這個程序,並沒有文件settings.ini存在,將創建settings.ini,我看到這樣的輸出:

Checking if file exists... 
About to yield file.create_async... 
(hangs) 

如果settings.ini存在,沒有數據被寫入到它,我看到這樣的輸出:

Checking if file exists... 
About to yield file.create_async... 
(hangs) 

我也有類似的問題,如果我嘗試重現該問題C.這是我的C代碼(它不復制上方的整個VALA例如,剛剛創建該文件的部分):

#include <glib.h> 
#include <gio/gio.h> 
#include <stdio.h> 

void create_callback(GObject *source_object, GAsyncResult *res, gpointer user_data); 
void write_contents(); 

GFile* file; 

void main(int argc, char** argv) { 
    g_type_init(); 

    fprintf(stderr, "Before file_new_for_path\n"); 
    file = g_file_new_for_path("settings.ini"); 

    fprintf(stderr, "Before file_query_exists\n"); 
    if (!g_file_query_exists(file, NULL)) { 
     fprintf(stderr, "Before file_create_async\n"); 
     g_file_create_async(
       file, 
       G_FILE_CREATE_REPLACE_DESTINATION, 
       G_PRIORITY_DEFAULT, 
       NULL, 
       create_callback, 
       NULL); 
     fprintf(stderr, "After file_create_async\n"); 
    } else { 
     fprintf(stderr, "File already exists. Before write_contents\n"); 
     write_contents(); 
     fprintf(stderr, "File already exists. After write_contents\n"); 
    } 

    while(TRUE) 
     ; 
} 

void create_callback(GObject *source_object, GAsyncResult *res, gpointer user_data) { 
    fprintf(stderr, "In create_callback. Before write_contents.\n"); 
    write_contents(); 
    fprintf(stderr, "In create_callback. After write_contents.\n"); 
} 

void write_contents() { 
    fprintf(stderr, "In write_contents\n"); 
} 

當運行該示例中,我看到這個輸出(假定settings.ini不存在):

Before file_new_for_path 
Before file_query_exists 
Before file_create_async 
After file_create_async 
(hangs) 

換句話說,create_callback永遠不會被調用。

我在做什麼錯?當我給他們打電話時,爲什麼不完成g_file_create_asyncg_file_replace_contents_async

回答

4

glib中的異步實現需要您運行消息循環。如果不是,您的回調將被調用的時間和方式是什麼?

所以在瓦拉只需添加:

var loop = new MainLoop(); 
loop.run(); 

而且在C:

GMainLoop *loop = g_main_loop_new(NULL, FALSE); 
g_main_loop_run(loop); 
g_main_loop_unref(loop)