【发布时间】:2017-02-02 17:21:16
【问题描述】:
标题可能有点误导,我的问题更多是关于为什么它以这种奇怪的方式工作。
所以我有一个布局,其中包含一个 TextView 和一个 ListView。我有一个长时间运行的异步方法,可以准备要在列表中显示的数据。所以初始代码是这样的:
protected async override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.MyView);
await SetupData();
}
private async Task SetupData(){
Task.Run(async () => {
var data = await new SlowDataLoader().LoadDataAsync();
// For simplicity setting data on the adapter is omitted here
});
}
它有效,从某种意义上说,它执行时没有错误。但是,活动显示为空白屏幕,甚至文本视图也仅在一定延迟后呈现。所以看起来任务实际上并没有异步运行。在两个“等待”调用上设置 ConfigureAwait(false) 没有帮助。将 SetupData() 调用移至 OnPostCreate、OnResume 和 OnPostResume 没有任何效果。当数据到达时,唯一使 TextView 立即出现并稍后呈现列表的是:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.MyView);
new Handler().PostDelayed(async ()=>{
await SetupData();
}, 100);
}
所以问题是,为什么不
await SetupData().ConfigureAwait(false);
解除阻塞?为什么我们必须强制延迟异步操作的开始以让 UI 完成渲染,即使(根据这个 http://www.wintellect.com/devcenter/paulballard/tasks-are-still-not-threads-and-async-is-not-parallel)SetupData 应该能够在这里作为单独的线程运行?
附言删除在适配器上设置数据的代码不会影响此行为 - 在呈现屏幕之前仍有延迟。所以我不在这里显示该代码。
【问题讨论】:
标签: c# android asynchronous xamarin xamarin.android