• .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位不允许线程池中线程直接操作控件,使得从任何线程中调用Controlinvoke,BeginInvoke,EndInvoke会将操作封装到创建Form的线程中.
    • 线程同步
      • FCL保证类型的static方法为线程安全.而不保证其它实例方法的线程安全性.
      • Cache.CPU在时机读取内存时,会将期望值以及该值附近的值放入Cache中.一个线程对内存写时实际上也是先写入Cache中.
        • 这对单核/单一线程CPU没有影响.
        • 但是对于多CPU中多线程访问同一Byte时会出现问题.多线程共享数据时应保持Cache的一致性.
      • Lock(Obj)保证了在异常发生时,Exit的调用,如果调用静态成员则TypeOf(Obj).
        • 问题:同步块好像拥有一个共有的同步DS与每个object关联,为避免公开锁,在类内定义一个Private Object o= new Object Lock(o);亦可使用已有的私有成员,但是如果内部调用了Lock(this)会死锁.
        • 不能使用值类型变量,对于未装箱的值类型,会在进入/退出时两次装箱,/解锁施加到两个不同的对象上.此时编译出错,应用装箱后的值.
        • 在Lazy Load中的双检索.
          1 if(obj ==null)
          2 {
          3      lock(obj);
          4      if(obj ==null) new object();    
          5 }
          Lazy Load
  • 相关阅读:
    去掉谷歌浏览器下input框自动填充的背景色
    ajax请求中动态显示问题
    Array对象的方法有
    请求页面的方法
    IE浏览器checkbox的样式问题
    property、classmethod和staticmethod总结
    面向对象和类
    内置函数补充map、reduce和filter等
    python实现控制台的进度条功能
    python常见内置函数
  • 原文地址:https://www.cnblogs.com/robyn/p/3786212.html
Copyright © 2020-2023  润新知