• ASP.NET本质论阅读----线程与异步


    线程

    概要:操作系统通过线程对程序的执行进行管理

    线程的数据结构:1.线程的核心对象(包含线程的当前寄存器状态),调用线程时-寄存器状态被加载到CPU中。

            2.线程环境块TEB:一块用户模式下的内存

            3.用户模式的堆栈:用户程序的局部变量和参数的存储

            4.内核模式的堆栈:用于访问操作系统时的堆栈

    线程分类:前台线程与后台线程。pS:所有前台线程终止,程序终止。

    线程执行任务分类:工作者线程和I/O线程

             工作者线程:计算密集的任务,CPU与线程资源充分利用

             I/O线程:CPU可以不必参与处理过程

    线程池

    线程的创建与启动

      由于线程用来表示代码的执行,所以需要通过委托进行,常见的3种线程委托

      1.ThreadStart委托

      public  delegate void ThreadStart();

      2.ParameterizedThreadStart委托

      public delegate void ParameterizedThreadStart(Object obj)

      3.TimerCallback委托

      Timer类实现

      public Timer(TimerCallback    //时间到时执行的委托

            ,State        //传递的参数

            ,DueTime      //创建到第一次执行的时差

            ,Period        //时间间隔

            )

    线程的状态  System.Thread.ThreadState

      

    线程上下文获取线程数据 ExecutionContext

    异步编程模式APM

    为了支持APM模式处理,.NET中对于消耗时间较长的操作,提供了BEGIN和END的方法,当调用Begin,启动异步线程第一步,同时将会保存第三步处理的回调方法,第三部操作将会在线程池的I/O线程上执行。

    例子:流的读取操作

    1.同步

    public override int Read(byte[] array ,int offset, int count);

    2.异步,第一步和第三步操作如下

    public override IAsyncResult BeginRead(

      byte[] array

      ,int offset

      ,int numBytes

      ,AsyncCallback userCallback

      ,object stateObject)

    userCallback:异步调用完成后,系统需要调用的回调方法

    stateObject:传递给回调方法的用户自定义的参数对象,一般来说,这个对象是使用异步操作的对象,用来完成结束操作。

    public override int EndRead( IAsyncResult syncResult);

    FileStream fs= new FileStream(path,open);
    
    IAsyncResult result= fs.BeginRead(buffer,0,4096,delegate(IAsyncResult ar)
    {
           int length= fs.EndRead(ar);},fs);

    基于事件的异步编程模式EPM

    支持EPM的类将有一个或多个后缀为Async的方法,同时还会有相应的名为Completed后缀的事件

    Async方法启动异步处理,而Completed事件则通过事件来宣告异步处理的完成

    无论处理完成、出现异常、终止异步处理,都必须调用Completed处理程序

    例子:WebClient发送一个请求 OpenReadAsync

    public void OpenReadAsync(Uri address)

    public event OpenReadCompletedEventHandler OpenReadCompleted

    处理该事件

    public static void OpenReadCallback2(Object sender,OpenReadCompletedEventArgs e)
    {
    stream reply=null;
    streamReader s=null;
    try
    { reply=(stream)e.Result;
    s=new StreamReader(reply);
    Console.WriteLine(s.ReadToEnd());
    }

    异步线程的状态和同步问题


    public interface IAsyncResult

    {

      object AsyncState{get;}

      WaitHandle AsyncWatiHanle{get;}

      bool CompletedSynchronously{get;}

      bool IsCompleted{get;}

    }

    处理管道中的异步问题

    将线程从等待中解放出来

    在启动线程操作时,将结束异步操作的第三部方法保存起来,在第一步之后,立即结束第一个线程,第二部等待处理完成后,取出保存的第三部处理方法,重新获取一个线程执行第三部,完成后,继续线程的原来的后续步骤。

    NextStep类
    public NextStep(EndEventHandler handler){
    this._endHandler=handler;
    }
    public void AsyncCallback(IAsyncResult ar)
    { this._endHandler(ar);
    }
    
    ReadFile类
    封装 IAsyncReault BeginReadFile(Object sender,EvnetArgs e,
       AsyncCallback cb, Object extraData);
           void EndReadFile(IAsyncResult ar);
    
    StepDemo 
    封装this._beginHandler和this._endHandler
    public void DoAsyncBeginWork()
    {
        NextSetp step=new (this._endhandler);
        this.beginHandler(this, , step.AsyncCallback,null);
    }
    
    调用
    StepDemo demo=new StepDemo();
    ReadFile rf=new ReadFile();
    demo.AddDoWork(rf.BeginHandler,rf.EndHandler);
    demo.DoAsyncBeiginWork();

     线程池

    public static class ThreadPool

     .net在每一个线程中维护一个应用程序分享的线程池,线程池提供队列,可以使用少量的线程完成多数线程的任务

    线程池工作原理:

      1.线程池的线程分为:计算密集的工作者线程 、 I/O线程

      2.线程池的线程从相应的任务队列中获取相应的任务进行处理,完成后,继续从队列获取任务,如果没有,在等待一段时间后,线程将被销毁

    加入工作者线程

      1.public delegate void WaitCallback{object state}

      2.public  static void main(){

        ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));

        static void ThreadProc(object stateInfo){};

    加入I/O线程

      调用Begin开头的方法,就是将线程排入线程池的I/O任务队列

    HttpApplication中的异步线程

    服务器接收一个请求时,httpRuntime将从HttpApplication池中获取一个HttpApplication对象处理请求,请求的处理过程被排入线程池中。

  • 相关阅读:
    get first、set all策略QWrap的FunctionH.mul变换 之一
    Maven学习:部分常见问题记录
    Hibernate异常记注:onetoone和catelog冲突
    RCP学习:Splash状态栏
    RCP学习:内容提示\代码提示\代码补全
    导出Eclipse Product的方法
    转载:OSGI组件依赖
    Type checking
    ObjectOriented Programming —— object(随记)
    一个不错的JavaScript模拟滚动条
  • 原文地址:https://www.cnblogs.com/ruanyifeng/p/2840866.html
Copyright © 2020-2023  润新知