Den*_*s K 8 c# android asynchronous xamarin.android xamarin
标题可能有点误导,我的问题更多的是为什么它以这种奇怪的方式工作.
所以我有一个具有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
});
}
Run Code Online (Sandbox Code Playgroud)
它的工作原理在某种意义上说它没有错误地执行.但是,活动显示为空白屏幕,即使文本视图仅在一定延迟后呈现.因此看起来任务实际上并非异步运行.在"await"调用上设置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);
}
Run Code Online (Sandbox Code Playgroud)
所以问题是,为什么不呢
await SetupData().ConfigureAwait(false);
Run Code Online (Sandbox Code Playgroud)
解锁流量?为什么我们必须强制延迟异步操作的开始以让UI完成渲染,尽管如此(根据http://www.wintellect.com/devcenter/paulballard/tasks-are-still-not-threads-and -async-is-not-parallel)SetupData应该可以在这里作为一个单独的线程运行?
ps删除在适配器上设置数据的代码不会影响此行为 - 在呈现屏幕之前仍有延迟.所以我不在这里展示代码.
Sus*_*ver 16
通过在UI Looper中等待,您在SetupData方法运行时阻止了线程上的进一步代码执行.
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
Task.Run(() => SetupData());
Console.WriteLine("UI Thread / Message Looper is not blocked");
}
void SetupData()
{
Task.Run(async () =>
{
Console.WriteLine($"Are we on the UI thread? {Looper.MainLooper.Thread == Looper.MyLooper()?.Thread}");
// Simulate a long running task
await Task.Delay(TimeSpan.FromSeconds(10));
Console.WriteLine("Done fetching/calculating data");
RunOnUiThread(() =>
{
// Update the data fetched/calculated on the UI thread;
Console.WriteLine($"Are we on the UI thread? {Looper.MainLooper.Thread == Looper.MyLooper().Thread}");
});
}).Wait();
Console.WriteLine("Done w/ SetupData");
}
Run Code Online (Sandbox Code Playgroud)
UI Thread / Message Looper is not blocked
Are we on the UI thread? False
Done fetching/calculating data
Are we on the UI thread? True
Done w/ SetupData
Run Code Online (Sandbox Code Playgroud)