首页 > 代码库 > .NET中的异步操作及线程同步
.NET中的异步操作及线程同步
- 执行异步操作
- CLR使用了WIN的线程处理能力,但保留了与其分离的权利.某些时候CLR的线程与Win的线程不是完全的匹配.
- 线程的系统开销较大,应限制其数量.
- 创建:分配并初始化一线程内核对象,保留1M的地址空间(用户模式),12KB的堆栈(内核模式),然后调用DLL函数通知进程中所有DLL操作来通知所有DLL操作又有一新的线程了.
- 销毁:进程中所有DLL收到一个死亡通知,且释放资源.且当仅有一个CPU时,每隔20ms执行一次上下文切换.
- CLR线程池.
- 每个进程一个,被该进程内的所有APP域共享,APP的一个请求会在队列中加一个条目,如果还有线程可用则使用之,如果没有创建一个新的,用完后归还为空闲.当一个线程空闲2Min后,唤醒并终止自己然后释放资源.少数线程节省资源,多数线程时充分利用多CPU.
- 上限.工作=25.I/O=1000.
- 未避免过快创建额外的线程.默认两线程创建间隔是500ms.但是可以使用SetMinThreads()来初始化多个线程.
- 试图访问受限资源时,CLR会进行CAS(检查所有AM是否有权访问资源),然后在有权限的AM中加入访问Code后,方法内部遍历调用线程的堆栈获取权限(调用UnSafe Code时不遍历,成为安全漏洞).当Tread运行时,权限与Thread相结合.
- 定时器.
- 1)System.Threading.Timer在另一线程上执行后台进程.
- 2)System.windows.Forms.Timer将定时器与调用线程相关联,触发后,Win将一Win.Timer插入Message队列,并将其分配到回调方法内,所有工作由一个Thread(设置Timer Thread的=执行的)完成(即Timer方法不可由多线程同时执行).
- 3)System.Timers. Timer:对1)的包装,派生自Component,只有将Timer至于设计界面上时才会使用它.
- 内部:所有Timer对象仅有一个CLR的进程,其知Next Timer何时到达,到达后,ClR线程调用池的Queue方法执行回调,如果回调方法执行时间过长,会再次触发池中多个对象同时执行(访问共享数据要同步锁).
- 使用Timer对象时要有Var Ref以防止被回收.
- 获知方法是否执行完毕的方法
- 1)Wait:直接调用EndXXX(),当操作完成时返回结果,未完成时挂起调用线程至完成.
- 2)轮询:让一个线程定期询问是否完成,耗时.
- 3)回调:工作项会被加入CLR的池队列中,之后由池线程将其取出并调用一个方法,在该回调方法内,用EndXXX来获取结果.
- 当方法出现异常,且有回调函数时,异常会被重新抛出.所以应该在EndXXX中Catch.
- 必须调用EndXXX来释放资源.但是多次调用时结果不定.
- IAsyncResult内部有一个对BeginXXX调用者的引用,必须用同一对象调用Begin/EndXXX,否则”非法操作Exception”(自定义对象可以).
- 无法取消一个未完成的异步操作.
- 每一次的BeginXXX都会创建一个IAsyncResult对象.会有性能上的损失.
- Win32的很多IO操作都不允许异步.
- 可以异步调用另一个方法,然后再该方法内调用IO操作.
- 由于16位为单线程,所以一个Form由一个线程创建,且必有使用该线程处理这个From的动作.32/64位不允许线程池中线程直接操作控件,使得从任何线程中调用Control的invoke,BeginInvoke,EndInvoke会将操作封装到创建Form的线程中.
- 线程同步
- FCL保证类型的static方法为线程安全.而不保证其它实例方法的线程安全性.
- Cache.CPU在时机读取内存时,会将期望值以及该值附近的值放入Cache中.一个线程对内存写时实际上也是先写入Cache中.
- 这对单核/单一线程CPU没有影响.
- 但是对于多CPU中多线程访问同一Byte时会出现问题.多线程共享数据时应保持Cache的一致性.
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。