2016-01-06 69 views
0

我試圖從解析(xamarin.ios使用C#)檢索用戶數據。我正在等待使用異步方法。我的挑戰是,每當我導航到應用程序中的tableView時,應該填充有問題的用戶數據,表總是空的。C#解析如何等待,直到查詢返回值

我想等到結果與code.I的其他部分繼續之前被送回曾嘗試使用ContinueWith()函數,但經常碰到一個生成錯誤 -

Cannot implicitly convert type 'void' to System.Collections.Generic.IEnumerable<Parse.ParseObject> 

我問題:

  1. 這是等待結果的最佳方式嗎?
  2. 如何解決構建錯誤?

這是我目前的執行:

public async void retrieveData(string username) 
    { 
     try 
     { 

      this.requests.ClearRequests(); 
      refreshed = false; 
      var query = ParseObject.GetQuery("Requests").WhereEqualTo("username", username); 

      IEnumerable<ParseObject> results = await query.FindAsync().ContinueWith(t =>{ 

       if(results != null) 
       { 
        foreach(ParseObject parseObject in results) 
        { 
         UserRequest request = new UserRequest(); 
         request.objectId = parseObject.ObjectId; 
         request.make = parseObject.Get<string> ("item1"); 
         request.model = parseObject.Get<string> ("item2"); 
         request.year = parseObject.Get<string> ("item3"); 
         request.userName = parseObject.Get<string> ("username"); 
         this.requests.addRequest (request); 
        } 
        refreshed = true; 
       } 



      }); 
} 
     catch(ParseException e) { 
      Console.WriteLine (e.Message + e.StackTrace); 
     } 
    } 

回答

1

你不應該需要一個ContinueWith ...這就是await應該辦理什麼。

awaitTask上等待,然後用適當的返回類型返回結果。 ContinueWith會返回一個Task,因此您必須從任務中獲取Result以使其可用。

更多關於這種類型的事情,你可能想看看Difference between await and ContinueWith

你可以嘗試這樣的事情。

public async void retrieveData(string username,) 
    { 
     try 
     { 

      this.requests.ClearRequests(); 
      refreshed = false; 
      var query = ParseObject.GetQuery("Requests").WhereEqualTo("username", username); 

      IEnumerable<ParseObject> results = await query.FindAsync(); 

      if(results != null) 
      { 
       foreach(ParseObject parseObject in results) 
       { 
        UserRequest request = new UserRequest(); 
        request.objectId = parseObject.ObjectId; 
        request.make = parseObject.Get<string> ("item1"); 
        request.model = parseObject.Get<string> ("item2"); 
        request.year = parseObject.Get<string> ("item3"); 
        request.userName = parseObject.Get<string> ("username"); 
        this.requests.addRequest (request); 
       } 
       refreshed = true; 
      } 
      //This is your refresh method for your TableView 
      this.RefreshTableView(); 
      //or, if in iOS 
      NSNotificationCenter.DefaultCenter.PostNotificationName("resultsRetrieved", null); 
     } 
     catch(ParseException e) { 
      Console.WriteLine (e.Message + e.StackTrace); 
     } 
    } 

要顯示的結果在tableView,我會建議tableView的清爽移動到results已經被檢索和分析後得到同步觸發一個單獨的方法。這與上面的this.RefreshTableView()調用一起顯示。

如果iOSXamarin,另一個選擇是post一個notificationNSNotificationCenterthe Xamarin documentation for which is here)。使用上面看到的PostNotificationName部分代替,然後在ViewControllers中添加一個觀察者,您想依賴這些數據。這是做如下:

做一個notificationToken對象:

NSObject notificationToken; 
在你的安裝方法

然後(你可以把你的ViewDidLoad這裏面):

void Setup() 
{ 
    notificationToken = NSNotificationCenter.DefaultCenter.AddObserver ("resultsRetrieved", RefreshData); 
} 

讓您RefeshData方法:

void RefreshData (NSString notifString) 
{ 
    this.tableView.ReloadData(); 
} 

然後,確保你處理通知觀察員,當你拆除類

void Teardown() 
{ 
    NSNotificationCenter.DefaultCenter.RemoveObserver (notificationToken); 
} 
+0

嗨Leejay,感謝您的快速回復。我明白那個。那麼如何在將屏幕顯示出來之前檢查任務是否已完成? – naffie

+0

好吧,現在我有一個基於該響應的新問題。圖片說明:1.我在用戶登錄後立即調用AppDelegate中的retrieveData()函數。2. tableview不是初始屏幕,等待有時間返回結果。 3.導航到桌面視圖顯示項目。 3.從列表中選擇一個項目會打開一個新窗口,您可以在其中編輯/創建一個新窗口。 4.點擊保存按鈕保存數據並從堆棧中彈出這個視圖,使我們回到桌面視圖。儘管如此,tableview並沒有反映出這些變化。我應該再次調用retrieveData()函數嗎? – naffie

+0

如果是,我應該在哪裏調用它?在我的tableViewController中,我應該在ViewWillAppear還是ViewDidLoad中工作?我目前使用ViewWillAppear,因爲ViewDidLoad只被調用一次。我相信在等待返回結果之前很久就會顯示該視圖。我已經嘗試調用保存按鈕委託內的retrieveData()。 – naffie

0

我有一個類似的問題,所以開始使用回調。我在Xamarin中使用它們。Android,很確定它們在Xamarin.iOS中可用。啓動任務方法

方法 - 請注意,我通過在這個類的方法作爲參數,從服務器調用數據

private async void updatedData() 
    { 
     await Utils.DataTasks.getNewLiveTips(populateTipsList); 
    } 

方法

public class DataTasks 
{ 
    public static async Task getAllData(Action<IEnumerable<ParseObjects>> callback) { 

     var query = new ParseQuery<ParseObjects>().OrderByDescending("updatedAt").Limit(5); 
     IEnumerable<ParseObjects> parseTips = await query.FindAsync(); 

     foreach (var tip in parseTips) 
     { 
     // Save data to DB if needed 
     } 

     callback(parseTips); 
    } 

我在第一種情況下作爲參數傳遞的方法現在稱爲

private void populateTipsList(IEnumerable<ParseObjects> results) 
    { 
     mAdapter = new TipAdapter(this.Activity, results); 
     mRecyclerView.SetAdapter(mAdapter); 

     refresher.Refreshing = false; 
    }