2016-05-12 132 views
0

你好,我想不通爲什麼這個異步操作不會等待C#異步操作不等待wp8.1

private async void scroller_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) 
    { 
     if (isLoadingMore) 
      return; 
     if (scroller.VerticalOffset > scrollContent.ActualHeight - (Frame.ActualHeight + 300)) 
      await LoadMoreItems(); 
    } 
    bool isLoadingMore = false; 
    private async Task LoadMoreItems() 
    { 
     isLoadingMore = true; 
     try 
     { 
      List<Items> itemsList = await App.ServiceClient.GetItems("bananas");//<-------Doesn't wait 
      foreach (Items in itemsList) 
       listView.Items.Add(c); 
     } 
     catch { } 
     isLoadingMore = false; 
    } 

這是後臺調用另一個異步任務

public async Task<List<Items>> GetItems(string selector) 
    { 
     HttpClient client = new HttpClient(); 
     var request = new HttpRequestMessage() 
     { 
      RequestUri = new Uri(myUrl), 
      Method = HttpMethod.Get, 
     }; 
     request.Headers.Add("Accept", "application/json"); 
     List<Items> items = null; 
     var task = await client.SendAsync(request).ContinueWith(
      async (s) => 
      { 
       try 
       { 
        string Result = await s.Result.Content.ReadAsStringAsync(); 
        if (s.Result.IsSuccessStatusCode) 
         items= JsonConvert.DeserializeObject<List<Items>>(Result); 
       } 
       catch 
       { } 
      }); 
     return items; 
    } 

問題是嵌套等待或在scoll視圖中。我發現this但我不認爲這是事實。

+0

請提供[MCVE](特別是 「最小」 的一部分)。到目前爲止,'async void'看起來很可疑 - 很可能你對預期行爲的期望與「忘卻遺忘」不同。 –

回答

1

事件處理程序是async void,所以這絕不會由UI被期待已久的,如果你不能處理多個ViewChanged事件,你有兩個選擇:

1 - 禁用滾動,同時有一個異步調用執行:

private async void scroller_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) 
{ 
    scroller.Enabled = false; 
    try 
    { 
     if (isLoadingMore) 
      return; 
     if (scroller.VerticalOffset > scrollContent.ActualHeight - (Frame.ActualHeight + 300)) 
      await LoadMoreItems(); 
    } 
    finally{ scroller.Enabled = true; } 
} 

2 - 別執行的代碼是否有另一個事件處理程序運行:

bool runnning = false 

private async void scroller_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e) 
{ 
    if(running) 
     return; 

    runnning = true; 
    try 
    { 
     if (isLoadingMore) 
      return; 
     if (scroller.VerticalOffset > scrollContent.ActualHeight - (Frame.ActualHeight + 300)) 
      await LoadMoreItems(); 
    } 
    finally{ running = false; } 
} 
+0

問題是在列表 itemsList,它不會等待完成後端調用,並連續到foreach它的空引用exceular – Quakenxt

+0

嗯,幾乎100%肯定,如果這是問題是因爲異步lambda,它是和使用TaskFactory.StartNew和Task.Run一樣,StartNew不會等待lambda是異步的,Run會不同,所不同的是Run爲你打開任務,所以如果你這樣做,它會等待:'var task = await client.SendAsync(request).ContinueWith(theLambda).Unwrap()'。以下是更多信息:https://msdn.microsoft.com/en-us/library/dd780917%28v=vs.110%29.aspx – Gusman