zoukankan      html  css  js  c++  java
  • C# 异步

    为什么要用异步

    简单说异步就是并行执行两件事,比同步执行快

    函数a执行3秒,函数b执行5秒,如果按顺序执行需要8秒(同步)

    使用异步的话,可以用异步先调用函数b,然后正常调用函数a,这时b还没执行完,a已经开始执行了,所以总时间应该会<=8秒


    什么时候用异步,什么时候用线程

    http://blog.csdn.net/onafioo/article/details/44342775


    BeginInvoke,EndInvoke,Invoke参数说明

    public <方法返回值类型> invoke(<输入和输出变量>)

    同步调用,参数就是委托函数的参数可以是多个参数


    public  IAsyncResult BeginInvoke( <输入和输出变量>, AsyncCallbackcallback result,  object asyncState) 

    启动异步调用,参数就是委托函数的参数,最后两个参数是异步回调函数,和一个object(这个object就是AsyncCallbackcallback 回调函数的参数IAsyncResult


    public <方法返回值类型>EndInvoke(<声明为ref或out的参数>, IAsyncResult result )

    用于检索异步调用结果,如果异步调用未结束就调用,那么就会阻塞等待异步调用结束,如果不调用这个EndInvoke那么就不会回收BeginInvoke启动的线程,造成资源浪费

    所以最好在异步结束后调用EndInvoke


        public interface IAsyncResult
        {
            // 摘要:
            //     获取用户定义的对象,它限定或包含关于异步操作的信息。
            //
            // 返回结果:
            //     用户定义的对象,它限定或包含关于异步操作的信息。
            object AsyncState { get; }
            //
            // 摘要:
            //     获取用于等待异步操作完成的 System.Threading.WaitHandle。
            //
            // 返回结果:
            //     用于等待异步操作完成的 System.Threading.WaitHandle。
            WaitHandle AsyncWaitHandle { get; }
            //
            // 摘要:
            //     获取一个值,该值指示异步操作是否同步完成。
            //
            // 返回结果:
            //     如果异步操作同步完成,则为 true;否则为 false。
            bool CompletedSynchronously { get; }
            //
            // 摘要:
            //     获取一个值,该值指示异步操作是否已完成。
            //
            // 返回结果:
            //     如果操作完成则为 true,否则为 false。
            bool IsCompleted { get; }
        }
    


    同步调用

    public delegate void TestDele(int num);
    public void showNum(int num)
    {
    	for(int i=0;i<10000000;i++)
    	{
    	}
    	Debug.Log(string.Format("num:{0}",num));
    }
    void main(){
    	TestDele testDele = new TestDele(showNum);
    	testDele.Invok(100);
    		
    }


    普通异步调用

    首先委托其实不单是个函数指针,实际是个类,类中有几个方法可用来实现异步BeginInvok,EndInvok等

    http://blog.csdn.net/onafioo/article/details/44354219

    public delegate void TestDele(int num);
    public void showNum(int num)
    {
    	for(int i=0;i<10000000;i++)
    	{
    	}
    	Debug.Log(string.Format("num:{0}",num));
    }
    void main(){
    	TestDele testDele = new TestDele(showNum);//这里定义委托时,内部自动生成BeginInvok,EndInvok等,这些方法用来实现异步
    	testDele.BeginInvok(100);
    	Debug.Log("start");
    	testDele.EndInvok();//这里必须结束,因为异步实际是从线程池中取了一个空闲线程,用完得归还
    	Debug.Log("over");	
    }

    1 执行testDele.BeginInvok

    2 不用等待showNum结束马上执行Debug.Log("start")

    3 等待showNum结束执行testDele.EndInvok();//没结束就阻塞

    4 最后执行Debug.Log("over");


    包含回调的异步调用,AsyncCallback(异步委托)

    首先c#异步函数是启动(BeginInvok)了一个线程池中的线程,所以要在函数结束后归还给线程池(EndInvok)

    所以问题来了怎么判断函数结束呢

    有4种方法http://blog.csdn.net/onafioo/article/details/44354219

    而AsyncCallback就是用来在异步函数结束后,使用回调的方法执行EndInvok

    用回调的好处

    1 不会形成阻塞

    2 不用自己循环等待函数结束再EndInvok,等函数结束后自动通过AsyncCallback调用  处理后事的函数执行EndInvok

    public delegate void TestDele(int num);
    public void showNum(int num){}
    void main(){
      TestDele testDele = new TestDele(showNum);//这里定义委托时,内部自动生成BeginInvok,EndInvok等,这些方法用来实现异步
      testDele.BeginInvok(100,new AsynvCallback(callBack),testDele);
      //testDele.BeginInvok(100,new AsynvCallback(callBack),null);//不含扩展参数
    }
    
    public void callBack(IAsyncResult ar)//用来处理后事(EndInvok)的函数,参数必须写IAsyncResult类型
    {
    	TestDele  dele =  (TestDele) ar.AsyncState;
    	//TestDele  dele = (TestDele)((AsyncResult)ar).AsyncDelegate;//没扩展参数时也可以获取到发出异步调用的委托 
    	dele.EndInvok();
    	//这里也可以写点其他有用的东西..
    }

    简易写法

    Action<object> action=(obj)=>method(obj);  
    action.BeginInvoke(obj,ar=>action.EndInvoke(ar),null);  


    其他异步的例子

  • 相关阅读:
    linux命令(一)
    Maven 打包不同环境
    Spring动态代理
    Spring MVC controller方法和jstl
    logback的使用
    从文本导入导出
    将临时全局表中的符合字段导入test数据库中
    将上传的新表导入临时全局表中
    建立临时表导入
    查询统计表以及删除表
  • 原文地址:https://www.cnblogs.com/nafio/p/9137556.html
Copyright © 2011-2022 走看看