异步方法冻结UI [英] async method freezes UI
问题描述
预期结果:
TestAsync
,工作线程执行LongTask
.
实际结果:
Ui线程执行所有操作
Ui thread executes everything
测试:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// [...]
_fab = root.FindViewById<FloatingActionButton>(...);
_fab.Click += ((sender, v) => TestAsync("fab"));
// [...]
}
private async void TestAsync(string origin)
{
await LongTask();
}
private async Task LongTask()
{
while (true) { } // Thread should hung here
}
结果:UI冻结.
测试2 : 为了确保UI能够执行所有操作,我改为进行了网络操作(Android的UI线程中不允许这样做)
Test 2: In order to make sure the UI is executing everything, I made a network operation instead (which is not allowed in the UI thread in Android)
public async Task<int> Network(string s)
{
URL url = new URL("http://www.randomtext.me/api/");
Java.IO.BufferedReader reader = new Java.IO.BufferedReader(new Java.IO.InputStreamReader(url.OpenStream()));
int count = 0;
string str;
while ((str = reader.ReadLine()) != null) {
count += str.Length;
}
reader.Close();
await Task.Delay(3000); // To make sure this method is compiled as async even though it isn't necessary
return count;
}
结果:NetworkOnMainThreadException
.
问题:
为什么在工作线程中不执行LongTask
或Network
方法?那么await
/async
是什么?
Why aren't LongTask
nor Network
methods executed in a worker thread ? What are await
/async
for then ?
谢谢.
推荐答案
然后一个工作线程执行LongTask.
and a worker thread executes LongTask.
不,那不会自己发生.您正在等待GUI线程,因此将其阻止.对于异步I/O,此模式是可以的,因为这将释放线程.
No, that won't happen by itself. You await from the GUI thread and so you will block it. This pattern is OK for async I/O because that will free up the Thread.
但是当您的情况受CPU限制时,异步/等待没有用,请使用Task.Run:
But when your case is CPU bound, there is no use for async/await, use Task.Run:
private void TestAsync(string origin)
{
Task.Run( LongTask);
}
这篇关于异步方法冻结UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!