2

ObservableCollection에 대해 ISupportIncrementalLoading 인터페이스를 구현하려고했습니다. 내 구현은 대부분 작동하지만 불확실한 상황에서는 이상하게 작동합니다. 여기 내 코드는 IncrementalCollection 클래스입니다. 페이지가로드, LoadMoreItemsAsync 기능은 때때로 일반적으로 두 번, 한 번만 호출 때로는 이상의 두 번 때 LoadMoreItemsAsync가 가변 시간 호출

public class IncrementalCollection<T> : ObservableCollection<T>, ISupportIncrementalLoading 
{ 
    private bool hasMoreItems; 
    private int currentPage; 
    private string filter; 

    private Func<string, int, Task<IList<T>>> func; 
    Action onLoadingStarts; 
    Action onLoadingEnds; 

    public IncrementalCollection(Func<string, int, Task<IList<T>>> func, Action onLoadingStarts, Action onLoadingEnds) 
    { 
     this.func = func; 
     this.hasMoreItems = true; 

     this.onLoadingStarts = onLoadingStarts; 
     this.onLoadingEnds = onLoadingEnds; 
    } 

    public void ResetCollection(string filter) 
    { 
     currentPage = 0; 
     this.filter = filter; 
     this.Clear(); 
    } 

    public bool HasMoreItems 
    { 
     get { return hasMoreItems; } 
    } 

    public IAsyncOperation<LoadMoreItemsResult> LoadMoreItemsAsync(uint count) 
    { 
     return DoLoadMoreItemsAsync(count).AsAsyncOperation<LoadMoreItemsResult>(); 
    } 

    private async Task<LoadMoreItemsResult> DoLoadMoreItemsAsync(uint count) 
    { 
     onLoadingStarts(); 
     var result = await func(this.filter, ++this.currentPage); 
     if (result == null || result.Count == 0) 
     { 
      hasMoreItems = false; 
     } 
     else 
     { 
      foreach (T item in result) 
       this.Add(item); 
     } 

     onLoadingEnds(); 
     return new LoadMoreItemsResult() { Count = result == null ? 0 : (uint)result.Count }; 
    } 
} 

최초의 이상한 행동

가 발생합니다. 콜은 콜렉션에 충분한 항목을 추가하기에 충분하므로 이상합니다. 나는 심지어 더 많은 데이터 (2-3 번)를 가져 오려고했지만 그 행동은 계속된다. IncrementalCollection 개체의 초기화 위치에 문제가있을 수 있습니다. 페이지를로드하는 데 시간이 오래 걸리는 것처럼 더 많은 호출이 LoadMoreItemsAsync 기능에 만들어집니다. 나는 이런 식으로 NavigationHelper_LoadState 컬렉션을 만들고있다. 나는 모든 페이지 생성자에
this.NavigationCacheMode = NavigationCacheMode.Disabled; 

을 추가하며 다시 탐색에 pageState을 저장하지 NavigationHelper을 변경하고 있지만

_users = new IncrementalCollection<User>((filter, page) => _dataService.GetUserList(url, filter, null, page), onLoadingStarts, onLoadingEnds); 

둘째 이상한 행동은 캐싱에 관한 것입니다. 웹 요청이 캐시 된 것처럼 느껴지므로 그 시간 내에 응답을 반환하는 것은 매우 어렵습니다.

public void OnNavigatedFrom(NavigationEventArgs e) 
{ 
    if (e.NavigationMode == NavigationMode.Back) 
     return; 

    var frameState = SuspensionManager.SessionStateForFrame(this.Frame); 
    var pageState = new Dictionary<String, Object>(); 
    if (this.SaveState != null) 
    { 
     this.SaveState(this, new SaveStateEventArgs(pageState)); 
    } 
    frameState[_pageKey] = pageState; 
} 

이러한 이상한 행동에 대한 도움을 주시면 감사하겠습니다.

또한 인터페이스에 대한 유용한 자습서가 LoadMoreItemsAsync 발사 조건을 설명합니다. WrapPanel 구현을 수정하려고하지만 어디서부터 시작해야할지 모르겠다. 이것은 아마도 약 ItemHeight이지만 여전히 구체적인 정보가 더 좋습니다.

미리 감사드립니다.

답변

0

ISupportIncrementalLoading 인터페이스에 버그가있는 것 같습니다. 해결 방법을 적용하여 여러 요청 문제를 해결했습니다. Create a ListView with LoadMoreItemsAsync on end of scroll.

foreach 루프를 넣은 후 Task.WhenAll 전화를 걸었습니다.

await Task.WhenAll(Task.Delay(50), Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => 
{ 
    foreach (T item in result) 
     this.Add(item); 
}).AsTask()); 
+0

여기 실제 수정 사항은 UI 스레드에서 '추가'를 호출한다는 것입니다. – Jon

관련 문제