Asynchronous programming #3

Thread

Use Thread in Applications

  • 在带界面的WPF、UWP、WinForm等程序种,若主线程执行耗时的操作,就会导致整个程序无响应。因为主线程同时还要处理消息循环,而渲染和鼠标键盘事件处理等工作都是在消息循环中执行的
  • 针对这种耗时的操作,一种流行的做法使启用一个worker线程,执行完操作后再更新到UI
  • 富客户端应用 的线程模型通常是:
    • UI控件只能从创建他们的线程来进行访问(通常是主线程)
    • 当想从worker线程更新UI时,应该把请求交给UI线程

Synchronization Contexts

  • 在System.ComponentModel下有一个抽象类:SynchronizationContext,它使得Thread Marshaling得到泛化
    • Thread Marshaling:把一些数据的所有权从一个线程交给了另一个线程

Thread Pool

  • 当开始一个线程时,将花费数百微秒来组织一些内容(如一个新的局部变量栈),产生了开销

  • 线程池可以节省这些开销:

    • 预先创建一个可循环使用的线程的池来减少创建新线程的开销
  • 线程池对于搞笑的并行编程和细粒度的并发是必不可少的

  • 关于c#中的线程池需要注意以下几点:

    • 不可以设置池线程的Name
    • 池线程都是后台线程
    • 阻塞池线程可能使性能降低
    • 池线程优先级可以被自由的更改,当它被释放回池的时候优先级将被还原为正常状态
    • 可以通过IsThreadPoolThread属性来判断是否为池线程
    • Task也使用线程池
  • 线程池中的整洁

    • 线程池提供了另一个功能,即确保不会产生CPU超额订阅(活跃的线程数超过CPU核数),超额订阅对性能影响很大
    • CLR通过对任务排队并对其启动进行节流限制来避免线程池中的超额订阅