编辑
我接受了乔恩的评论并重新审视了整个事情.事实上,它是阻塞UI线程.我必须以某种方式弄乱我的初步测试.字符串"OnResume exits" 在 SomeAsync完成后写入.如果方法被更改为使用await Task.WhenAll(t)它将(如预期)不阻止.感谢您的投入!我首先考虑删除这个问题,因为最初的假设是错误的,但我认为答案包含了不应丢失的有价值的信息.
原帖:
试图了解async-await更深入的内部结构.以下示例来自使用Xamarin的Android应用.OnResume()在UI线程上执行.
SomeAsync()开始一个新任务(=它产生一个线程).然后它Task.WaitAll()用于执行阻塞等待(如果WhenAll()是更好的选择,现在不讨论).Task.WaitAll()运行时没有被阻止.所以SomeAsync()不在UI线程上运行.这意味着创建了一个新线程.如何await"知道"它必须在这里产生一个线程 - 它会一直这样做吗?如果我改变了WaitAll()to 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);
}
Run Code Online (Sandbox Code Playgroud)
简单:它永远不会产生一个线程await.如果等待已经完成,它就会继续运行; 如果等待还没有完成,它只是告诉等待实例添加一个延续(通过一个相当复杂的状态机).当正在完成的事情完成时,将调用continuation(通常通过sync-context,如果有的话 - 在标记工作完成的线程上同步).然而!理论上,sync-context可以选择将事物推送到线程池(大多数UI同步上下文,但是,将事物推送到UI线程).
| 归档时间: |
|
| 查看次数: |
182 次 |
| 最近记录: |