0

我想在運行任務(從API獲取一些數據)後在UI線程中更改我的UI元素(隱藏進度條併爲listview分配數據)。 API的問題我沒有找到,數據在所有情況下都會返回。有時在運行Task之後執行代碼(在RunOnUiThread中)變得反應遲鈍,特別是當我以Debug模式運行沒有任何斷點的代碼時。當我在調用任務之前捕獲斷點並繼續運行時,所有工作都正常。使用ContinueWith或委託運行一些任務後不運行RunOnUiThread

protected override void OnCreate(Bundle savedInstanceState) 
     { 
      base.OnCreate(savedInstanceState); 
      _userData = ServiceLocator.GetService<IAuthService>().GetUserData(); 
      _wallsViewPresenter = ViewPresenterHelper.CreateViewPresenter<WallViewPresenter, IWallView, WallActivity>(this); 
      _listView = FindViewById<ListView>(Resource.Id.postList); 

      progressBar = FindViewById<ProgressBar>(Resource.Id.progressBar1); 
      Task.Run(async() => { 
       profile = await _wallsViewPresenter.GetProfile(int.Parse(_userData.Profile)); 
       WallModel wall = SerializationService.DeSerialize<WallModel>(profile.Wall); 
       _posts = (List<PostModel>) (wall.Posts.ToList());       
      }).ContinueWith(ar => 
      { 
       RunOnUiThread(() => { 
        progressBar.Visibility = ViewStates.Gone; 
        _postListAdapter = new PostListAdapter(this, _posts); 
        _listView.Adapter = _postListAdapter; 
        SetListViewHeader(); 
        _listView.AddHeaderView(_header); 
        FindViewById<TextView>(Resource.Id.details).Text = profile.Name; 
       }); 
      });    
     } 

版本與委託:

 protected override void OnCreate(Bundle savedInstanceState) 
    { 
     base.OnCreate(savedInstanceState); 
     _userData = ServiceLocator.GetService<IAuthService>().GetUserData(); 
     _wallsViewPresenter = ViewPresenterHelper.CreateViewPresenter<WallViewPresenter, IWallView, WallActivity>(this); 
     _listView = FindViewById<ListView>(Resource.Id.postList); 
     progressBar = FindViewById<ProgressBar>(Resource.Id.progressBar1); 
     Task.Run(async() => { 
      profile = await _wallsViewPresenter.GetProfile(int.Parse(_userData.Profile)); 
      WallModel wall = SerializationService.DeSerialize<WallModel>(profile.Wall); 
      _posts = (List<PostModel>) (wall.Posts.ToList()); 
      if (_posts.Count != 0) 
      { 
       DataPopulated?.Invoke(this, true); 
      } 
     }); 
     DataPopulated += (sender, e) => { 
      RunOnUiThread(() => { 
       progressBar.Visibility = ViewStates.Gone; 
       _postListAdapter = new PostListAdapter(this, _posts); 
       _listView.Adapter = _postListAdapter; 
       SetListViewHeader(); 
       _listView.AddHeaderView(_header); 
       FindViewById<TextView>(Resource.Id.details).Text = profile.Name; 
      }); 
     }; 
    } 

回答

0

ContinueWith是非常危險的,低層次的API;不應該在這裏使用。此外,與async/await,不需要RunOnUIThread

由於您調用的方法已經是異步的,所以也可能不需要Task.Run

簡體版:

protected override async void OnCreate(Bundle savedInstanceState) 
{ 
    base.OnCreate(savedInstanceState); 
    _userData = ServiceLocator.GetService<IAuthService>().GetUserData(); 
    _wallsViewPresenter = ViewPresenterHelper.CreateViewPresenter<WallViewPresenter, IWallView, WallActivity>(this); 
    _listView = FindViewById<ListView>(Resource.Id.postList); 

    progressBar = FindViewById<ProgressBar>(Resource.Id.progressBar1); 
    profile = await _wallsViewPresenter.GetProfile(int.Parse(_userData.Profile)); 
    WallModel wall = SerializationService.DeSerialize<WallModel>(profile.Wall); 
    _posts = (List<PostModel>) (wall.Posts.ToList());       

    progressBar.Visibility = ViewStates.Gone; 
    _postListAdapter = new PostListAdapter(this, _posts); 
    _listView.Adapter = _postListAdapter; 
    SetListViewHeader(); 
    _listView.AddHeaderView(_header); 
    FindViewById<TextView>(Resource.Id.details).Text = profile.Name; 
} 
+0

感謝,但調用方法之後'個人資料=等待_wallsViewPresenter.GetProfile(int.Parse(_userData.Profile));'代碼變得反應遲鈍和進度繼續工作(不牆根) –

+1

@ IgorLevkivskiy:聽起來像你的「異步」方法實際上是同步的。在這種情況下,一個快速的解決方法是將中間的4行代碼封裝在'await Task.Run(()=> {'...'});'中。 –