2013-05-16 53 views
1

這可能是一個愚蠢的問題。但是當我修改Live SDK的一個例子時,出現了一個奇怪的問題。爲什麼我的List在函數調用中分配後爲空?

我在想根本原因是異步函數GetAll()被同步使用。

下面是代碼片段,我把問題作爲註釋。提前致謝!

class SkyeDriveViewModel: INotifyPropertyChanged 
{ 
    private List<SkyDriveItem> folderList = null; 
    public List<SkyDriveItem> FolderList 
    { 
     get { return folderList; } 
     private set 
     { 
      if (value != folderList) 
      { 

       folderList = value; 
       NotifyPropertyChanged("FolderList"); 
      } 
     } 
    } 

    private async void GetAll(string desiredPath) 
    { 
     FolderList = new List<SkyDriveItem>(); 

     this.liveClient = new LiveConnectClient(SkyDrivePage.Session); 
     try 
     { 
      LiveOperationResult operationResult = await this.liveClient.GetAsync(desiredPath); 
      dynamic result = operationResult.Result; 

      dynamic items = result.data; 
      foreach (dynamic item in items) 
      { 
       SkyDriveItem newItem = new SkyDriveItem(item); 
       if (newItem.IsFolder) 
       { 
        FolderList.Add(newItem); 
       } 

      } 

     } 
     catch (LiveConnectException e) 
     { 
     } 
     //**till here, FolderList was assigned** 
    } 

    public void InitList() 
    { 
     Debugger.Log(); 
     GetAll(SKYDRIVEINITPATH); 
     Debugger.LogWhen(eDebugger.LogTiming.Exit); 
     //**till here, FolderList had zero item** 
    } 

} 

回答

5

通常有一個async void函數是一個警告標誌。你應該只有一個事件處理程序的方法。 GetAll的適當返回類型是Task,或者甚至可能是Task<List<SkyDriveItem>>

問題是調用GetAll只會執行代碼,直到它遇到第一個await調用,此時它將返回調用方,並且該方法的其餘部分將被異步執行。

這裏的問題是,因爲方法是void你無法知道它什麼時候完成。你有一個「消防和忘記」的方法,永遠不知道你的清單何時準備就緒。如果GetAll返回一個任務,那麼你可以await該任務,並確保您的列表實際上已填充。

+0

+1。如果調用函數*必須*同步,'GatAll'應該返回'Task'並且你可以調用'Wait'結果。 –

+0

@AlexeiLevenkov如果調用者需要它是同步的,那麼該方法可能不應該異步開始... – Servy

+0

@Servy感謝您的答案! – tao

相關問題