2013-03-15 59 views
0

請原諒我的無知,但我是異步編程的新手,我似乎無法弄清楚這一點。異步SQLite時序的問題

我有許多SQLite操作的Windows Phone 8應用程序。

我一直有問題,偶爾在數據庫中設置一個值,但顯然沒有及時設置它的檢索時間。但這並不一致,這就是爲什麼我想知道它是否是線程問題。

我對插入的記錄,像這樣的方法:

public async Task<string> getSetting(Settings setting) 
    { 
     string returnString = ""; 
     string setName = setting.getName(); 


     try 
     { 
      SQLiteAsyncConnection conn = new SQLiteAsyncConnection(Path.Combine(ApplicationData.Current.LocalFolder.Path, "newDatabase"), true); 
      var query = conn.Table<ClientSettings>().Where(x => x.ID == setName); 
      var result = await query.ToListAsync().ConfigureAwait(false); 

      foreach (var item in result) 
      { 

       returnString = item.Value; 
      } 
     } 
     catch (Exception e) 
     { 
      System.Diagnostics.Debug.WriteLine("\nERROR: " + e); 

     } 
     return ret; 
    } 

我也有檢索這些方法:

public async Task<string> getSetting(Settings setting) 
    { 
     string returnString = ""; 
     string setName = setting.getName(); 


     try 
     { 
      SQLiteAsyncConnection conn = new SQLiteAsyncConnection(Path.Combine(ApplicationData.Current.LocalFolder.Path, "newDatabase"), true); 
      var query = conn.Table<MySettings>().Where(x => x.ID == setName); 
      var result = await query.ToListAsync().ConfigureAwait(false); 

      foreach (var item in result) 
      { 
       returnString = item.Value; 
      } 
     } 
     catch (Exception e) 
     { 
      System.Diagnostics.Debug.WriteLine("\nERROR: " + e); 

     } 
     return returnString; 
    } 

如果我這樣稱呼它的主頁:

var insert = Constants.getData().setSetting(ExampleSetting, "userIDtest", false).Result; 
string retrieving = Constants.getData().getSetting(ExampleSetting).Result; 

它工作正常,並在「檢索」的下一行打印控制檯是正確的值。但是,在許多其他情況下 - 如果setSetting不返回值而是void,則該設置似乎沒有及時設置,並且getSetting不會返回設置的值。

此外,在部分應用程序中,系統會提示用戶輸入一些信息,然後將其置於數據庫中並立即用於xml web服務。儘管代碼看起來和上面完全一樣,但這似乎沒有及時設置。

這是這樣做的正確方法嗎?有沒有更好的方法來設置SQLite記錄,確保它們被設置,而不鎖定UI線程?

+0

你有'getSetting'代碼在上面顯示兩次。我想你也想顯示'setSetting'。 – 2013-03-15 00:50:41

回答

1

您應該使用await代替Task.Result

var insert = await Constants.getData().setSetting(ExampleSetting, "userIDtest", false); 
string retrieving = await Constants.getData().getSetting(ExampleSetting); 

上面的代碼將等待你的數據庫調用完成,但不會阻止用戶界面。請注意,這不適用於控制檯應用程序 - 它只適用於GUI應用程序。

除此之外,你的getSetting代碼看起來很好。我無法對setSetting發表評論,因爲它沒有顯示在你的問題中。

1

如果setSetting沒有返回值,但反而無效

如果setSetting回報void,那麼你有沒有當async操作完成得知。一個async方法應該從來沒有返回void(除非它是一個事件處理程序)。

如果您不想從async方法返回值,請使方法返回值爲Task。這樣,您仍然可以在返回的任務await之前確保setSetting已完成,然後再繼續。

+0

感謝您的回覆。此外,您的文章「異步編程最佳實踐」和您的博客文章「不要阻止異步代碼」非常有幫助! – 2013-03-15 17:00:15