C# 多线程学习笔记 - 1
程序员文章站
2022-08-23 17:29:52
本文主要针对 GKarch 相关文章留作笔记,仅在原文基础上记录了自己的理解与摘抄部分片段。 遵循原作者的 "CC 3.0 协议" 。 如果想要了解更加详细的文章信息内容,请访问下列地址进行学习。 原文章地址: "https://blog.gkarch.com/threading/part2.htm ......
本文主要针对 gkarch 相关文章留作笔记,仅在原文基础上记录了自己的理解与摘抄部分片段。
遵循原作者的 cc 3.0 协议。
如果想要了解更加详细的文章信息内容,请访问下列地址进行学习。原文章地址:
基础知识
- 静态字段是在所有线程当*享状态的。
- 一个线程被阻塞时,不会消耗 cpu 资源。
- join 可以等待另一个线程结束,sleep 可以将线程阻塞指定的时间,两者使用时线程都是阻塞状态。
- join 可以设置超时时间,当线程执行超过指定时间返回 false。
-
thread.sleep(0)
会释放当前时间片,将 cpu 资源让出给其他线程。 -
thread.sleep(0)
作用与thread.yield()
作用一样,后者只会让出给当前核心的其他线程。 -
thread.yield()
执行时会影响到程序的话,基本可以确定代码存在 bug。 - 在使用 lambda 表达式启动线程并传入变量的时候,不要在启动线程之后更改被捕获变量的值。
- 线程分为前台线程与后台线程,当所有前台线程中止时,程序自动退出。
- 可以显式地提高线程优先级,但可能会导致线程饥饿。
线程池
由于线程创建成本高昂(私有局部变量栈,每个线程默认占用 1 mb内存),所以一般都会使用线程池来进行线程的创建与回收。
线程池线程可以临时更改其优先级,在回收后会恢复默认状态。
开发人员可以通过
thread.currentthread.isthreadpoolthread
属性查询线程是否运行在线程池中。通过查询 task.result 会导致当前线程阻塞,直到任务执行完成,如果发生错误,则会将异常包装到
aggregateexception
异常内进行抛出。-
通过异步委托可以快速创建一个工作线程。
- 创建目标方法委托。
- 在委托上调用
begininvoke()
方法,保存其iactionresult
返回值。 - 需要返回结果时,调用
endinvoke()
方法,传递保存的iactionresult
对象。
class program { static void main(string[] args) { func<string, int> work = work; var result = work.("测试",null,null); console.writeline("获得结果"); work.endinvoke(result); } public static int work(string inputstr) { console.write(thread.currentthread); return inputstr.length; } }
注意:
上述代码在 .net core 平台上是无法运行的。
异步委托在调用
begininvoke()
的时候可以传入回调方法。线程池可以通过
threadpool.setmaxthreads
与threadpool.setminthreads
进行优化。