C#基础面试问题
yield的作用
[collapse title=”details”]
yield需配合IEnumerable<T>一起使用,能在一个函数中支持多次(不是多个)返回,其本质和async/await一样,也是状态机。
如果不使用yield,需实现IEnumerable<T>,它只暴露了GetEnumerator<T>,这样确保yield是可重入的,比较符合人的习惯。
在python中也有yield,就是迭代器每次调用时分别得到的值。
[/collapse]
对比Task和Thread
[collapse title=”details”]
Task和Thread都能创建用多线程的方式执行代码,但它们有较大的区别。
Task较新,发布于.NET 4.5,能结合新的async/await代码模型写代码,它不止能创建新线程,还能使用线程池(默认)、单线程等方式编程,在UI编程领域,Task还能自动返回UI线程上下文,还提供了许多便利API以管理多个Task
[/collapse]
简述await的作用和原理,并说明和GetResult()有什么区别
[collapse title=”details”]
await 关键字提供了一种非阻塞方式来启动任务,然后在此任务完成时继续执行。
从状态机的角度出发,await的本质是调用Task.GetAwaiter()的UnsafeOnCompleted(Action)回调,并指定下一个状态号。
从多线程的角度出发,如果await的Task需要在新的线程上执行,该状态机的MoveNext()方法会立即返回,此时,主线程被释放出来了,然后在UnsafeOnCompleted回调的action指定的线程上下文中继续MoveNext()和下一个状态的代码。
而相比之下,GetResult()就是在当前线程上立即等待Task的完成,在Task完成前,当前线程不会释放。
[/collapse]