我想在运行Task(从API获取一些数据)之后在UI线程中更改我的UI元素(隐藏进度条并为listview分配数据)。我没有找到API的问题,在所有情况下都返回数据。有时在运行Task之后执行代码(在RunOnUiThread中)变得没有响应,尤其是当我在调试模式下运行没有任何断点的代码时。当我在调用Task并继续运行之前捕获断点时,一切正常。
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 :(得分: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;
}