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