【发布时间】:2014-04-02 07:14:22
【问题描述】:
编辑
我接受了 Jon 的评论并重试了整个过程。事实上,它阻塞了 UI 线程。我一定以某种方式搞砸了我的初始测试。 在 SomeAsync 完成后写入字符串“OnResume exits”。如果方法更改为使用await Task.WhenAll(t),它将(如预期的那样)不会阻塞。感谢您的输入!
我最初考虑删除问题是因为最初的假设是错误的,但我认为答案包含不应丢失的有价值信息。
原帖:
试图了解 async-await 的更深层次的内部结构。下面的示例来自使用 Xamarin 的 Android 应用程序。 OnResume() 在 UI 线程上执行。
-
SomeAsync()开始一个新任务(= 它产生一个线程)。然后它使用Task.WaitAll()执行阻塞等待(我们现在不讨论WhenAll()是否是更好的选择)。 - 我可以看到,
Task.WaitAll()正在运行时 UI 没有被阻止。所以SomeAsync()不会在 UI 线程上运行。这意味着创建了一个新线程。
await 是如何“知道”它必须在这里生成一个线程的——它会一直这样做吗?如果我将WaitAll() 更改为WhenAll(),就不需要像我理解的那样快的额外线程。
// This runs on the UI thread.
async override OnResume()
{
// What happens here? Not necessarily a new thread I suppose. But what else?
Console.WriteLine ("OnResume is about to call an async method.");
await SomeAsync();
// Here we are back on the current sync context, which is the UI thread.
SomethingElse();
Console.WriteLine ("OnResume exits");
}
Task<int> SomeAsync()
{
var t = Task.Factory.StartNew (() => {
Console.WriteLine("Working really hard!");
Thread.Sleep(10000);
Console.WriteLine("Done working.");
});
Task.WhenAll (t);
return Task.FromResult (42);
}
【问题讨论】:
-
Task.WaitAll()应该阻塞 UI 线程。您通常会使用Task.WhenAll异步等待。这可能是某些 Xamarin 特定的行为,或者您可能误诊。请注意,这不是您的真实代码 - 它不会编译,因为OnResume的方法声明无效并且SomeAsync既没有声明为async也没有返回任何内容。
标签: c# async-await