2017-09-05 3 views
1

ListView 항목을 선택하면 실행되는 코드가 있습니다. 이 코드는 실행하는 데 상당한 시간이 걸릴 수 있으므로 실행중인 동안 ActivityIndicator을 표시하려고합니다.XAMarin Forms ActivityIndicator를 표시하기 위해 async/await를 올바르게 사용하는 방법

나는 ActivityIndicator에 관한 많은 게시물을 읽었으며 제대로 설정했다고 생각합니다. 나는 내 문제가 프로세스 동안 UI가 완전히 멈 추었 기 때문에 UI 스레드를 차단하는 실행 코드로 인한 것임을 확신한다.

async를 사용하여 찾을 수있는 모든 변형을 처리했기 때문에 운이 좋지 않습니다. 아직 잘못 처리하고 있다고 가정하고 있습니다. 그래서

private ListItem selectedList; 
public ListItem SelectedList 
{ 
    get 
    { 
     return selectedList; 
    } 
    set 
    { 
     if (selectedList != value) 
     { 
      var oldValue = selectedList; 
      selectedList = value; 
      buildThisList(); 
     } 
    } 
} 

private async void buildThisList() 
{ 
    StatusBarIsVisibile = true; 
    ThisList = Task.Run(async() => 
    { 
     return await buildBnBList(SelectedList, selectedLocation, 
         thisYearList.ListId) 
         .ConfigureAwait(false); 
    }).Result; // 1.8 seconds 
    StatusBarIsVisibile = false; 
    ThisList.MainVM = this; 
    ThisList.BuildView(); 
    PIShowListHeaderText = SelectedList.Title.Trim(); 
} 

private async Task<BnBList> buildBnBList(ListItem pSelectedList, State pselectedLocation, int pListId) 
{ 
    BnBList newList = new BnBList(pSelectedList, pselectedLocation, pListId); 
    List<BirdsnBflysMaster> bbfList = 
     App.BnBRepo.GetBirdsnBflys(selectedList.ListType); // 1.3 seconds 
    Lists parentList = App.BnBRepo.GetAList(SelectedList.ListId); // .5 seconds 
    BnBItem newBnBItem; 
    foreach (BirdsnBflysMaster bbf in bbfList) // .4 seconds 
    { 
     newBnBItem = new BnBItem(parentList, bbf, selectedLocation, newList, thisYearList.ListId); 
     newList.ListAll.Add(newBnBItem); 
     if (newBnBItem.ListTypeID == "Bird") 
     { 
      ... 
     } 
     else 
     { 
      ... 
     } 
    }    
    return newList; 
} 

:

  • buildThisList이 때 SelectedList 속성 변경 호출되는

    여기 내 코드입니다.

  • buildThisList은 시간이 많이 소요되는 프로세스 인 buildBnBList입니다.
  • buildBnBList에는 비동기 적으로 수행되는 내용이 없습니다.
  • StatusBarIsVisibleActivityIndicatorIsVisibleIsRunning에 모두 바인딩됩니다.

buildBnBList을 실행하면 UI 스레드가 차단되지 않도록 어떻게 코딩 할 수 있습니까?

답변

3

예. 교착 상태의 원인이 될 수있는 비동기 코드가 포함 된 혼합 차단 (.Result)입니다. async void은 짝수 핸들러가 아닌 한 피해야합니다.

그러면 왜 그렇게하지 않으시겠습니까?

이벤트 및 이벤트 처리기를 만듭니다.

public event EventHandler ListSelected = delegate { } 

하면이 이제

private async void OnListSelected(object sender, EventArgs e) { 
    StatusBarIsVisibile = true; 
    ThisList = await buildBnBList(SelectedList, selectedLocation, thisYearList.ListId); 

    StatusBarIsVisibile = false; 
    ThisList.MainVM = this; 
    ThisList.BuildView(); 
    PIShowListHeaderText = SelectedList.Title.Trim(); 
} 

당신은 분명히 (초기 과정의 라이프 사이클에서) 발생 에 가입 할 이벤트 핸들러

this.ListSelected += OnListSelected; 

을 만들 수 있도록해야한다 필요에 따라 이벤트를 개최하십시오.

private ListItem selectedList; 
public ListItem SelectedList { 
    get { 
     return selectedList; 
    } 
    set { 
     if (selectedList != value) { 
      var oldValue = selectedList; 
      selectedList = value; 
      OnListSelected(this, EventArgs.Empty); 
     } 
    } 
} 
+0

입력 해 주셔서 감사합니다. 네가 제안한 걸 이해할 것 같아. 코드에서 구현했지만 차이는 없습니다. 실행하기 전에 StatusBarIsVisibile = true로 설정하면 ActivityIndicator가 회전합니다. 목록 항목을 클릭하면 회 전자가 중지되고 OnListSelected가 완료 될 때까지 UI에서 아무 것도 일어나지 않습니다. 이 시점에서 ActivityIndicator가 다시 회전하기 시작하고 선택한 항목이 강조 표시됩니다. – DaveS