当前位置:  编程技术>.net/c#/asp.net

深入分析C#异步编程详解

    来源: 互联网  发布时间:2014-10-20

    本文导语:  同步方法和异步方法的区别同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果异步方法则在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作异步编程概览.NET Framework 允许您异步调...

同步方法和异步方法的区别
同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果
异步方法则在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作
异步编程概览
.NET Framework 允许您异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名
的 BeginInvoke 和 EndInvoke 方法。
BeginInvoke 方法用于启动异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数(将在稍后描述)。
BeginInvoke 立即返回,不等待异步调用完成。
BeginInvoke 返回 IasyncResult,可用于监视调用进度。
EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果异步调用未完成,EndInvoke 将一直阻塞到
异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 ByRef 和 ByRef)以及由
BeginInvoke 返回的 IAsyncResult。
四种使用 BeginInvoke 和 EndInvoke 进行异步调用的常用方法。调用了 BeginInvoke 后,可以:
1.进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。
2.使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用
EndInvoke。这里主要是主程序等待异步方法,等待异步方法的结果。
3.轮询由 BeginInvoke 返回的 IAsyncResult,IAsyncResult.IsCompeted确定异步调用何时完成,然后调用 EndInvoke。此处理个人认为与
相同。
4.将用于回调方法的委托传递给 BeginInvoke。该方法在异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。这是在强制装
换回调函数里面IAsyncResult.AsyncState(BeginInvoke方法的最后一个参数)成委托,然后用委托执行EndInvoke。
警告   始终在异步调用完成后调用 EndInvoke。
以上有不理解的稍后可以再理解。
 
例子
1)先来个简单的没有回调函数的异步方法例子
请再运行程序的时候,仔细看注释,对理解很有帮助。还有,若将注释的中的两个方法都同步,你会发现异步运行的速度优越性。
代码如下:

using System;
 namespace ConsoleApplication1
 {
     class Class1
     {
         //声明委托
         public delegate void AsyncEventHandler();

         //异步方法
         void Event1()
        {
            Console.WriteLine("Event1 Start");
            System.Threading.Thread.Sleep(4000);
            Console.WriteLine("Event1 End");
        }
        // 同步方法
        void Event2()
        {
            Console.WriteLine("Event2 Start");
            int i=1;
            while(i 0)
        {
            // 准备 Char 数组缓冲区,用于向 Unicode 转换
            Char[] charBuffer = new Char[BUFFER_SIZE];
            // 将字节流转换为 Char 数组,然后转换为字符串
            // len 显示多少字符被转换为 Unicode
            int len = rs.StreamDecode.GetChars(rs.BufferRead, 0, read, charBuffer, 0);
            String str = new String(charBuffer, 0, len);
            // 将最近读取的数据追加到 RequestData stringbuilder 对象中,
            // 该对象包含在 RequestState 中
            rs.RequestData.Append(str);
            // 现在发出另一个异步调用,读取更多的数据
            // 请注意,将不断调用此过程,直到
            // responseStream.EndRead 返回 -1
            IAsyncResult ar = responseStream.BeginRead(rs.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
        }
        else
        {
            if (rs.RequestData.Length > 1)
            {
                // 所有数据都已被读取,因此将其显示到控制台
                string strContent;
                strContent = rs.RequestData.ToString();
                Console.WriteLine(strContent);
            }
            // 关闭响应流
            responseStream.Close();
            // 设置 ManualResetEvent,以便主线程可以退出
            allDone.Set();
        }
        return;
    }
}

在这里有回调函数,且异步回调中又有异步操作。
首先是异步获得ResponseStream,然后异步读取数据。
这个程序非常经典。从中可以学到很多东西的。我们来共同探讨。
总结
上面说过,.net framework 可以异步调用任何方法。所以异步用处广泛。
在.net framework 类库中也有很多异步调用的方法。一般都是已Begin开头End结尾构成一对,异步委托方法,外加两个回调函数和AsyncState参数,组成异步操作的宏观体现。所以要做异步编程,不要忘了委托delegate、Begin,End,AsyncCallBack委托,AsyncState实例(在回调函数中通过IAsyncResult.AsyncState来强制转换),IAsycResult(监控异步),就足以理解异步真谛了。

    
 
 

您可能感兴趣的文章:

  • 深入C#任务管理器中应用程序选项隐藏程序本身的方法详解
  • 深入C# 内存管理以及优化的方法详解
  • 深入c# Func委托的详解
  • C# 多态性的深入理解
  • 深入C#中使用SqlDbType.Xml类型参数的使用详解
  • 深入C# winform清除由GDI绘制出来的所有线条或图形的解决方法
  • 深入Unix时间戳与C# DateTime时间类型互换的详解
  • C# interface与delegate效能比较的深入解析
  • C#中IList<T>与List<T>的区别深入解析
  • 深入分析C#中WinForm控件之Dock顺序调整的详解
  • C#中静态的深入理解
  • C#泛型约束的深入理解
  • C#之CLR内存深入分析
  • 深入解析c#中枚举类型的定义与使用
  • 深入c#绘制验证码的详解
  • 深入c# 类和结构的区别总结详解
  • 深入c# GDI+简单绘图的具体操作步骤(一)
  • 深入探讨C#中的结构struct
  • 深入理解C# abstract和virtual关键字
  • c#方法中调用参数的值传递方式和引用传递方式以及ref与out的区别深入解析
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 深入JDBC sqlserver连接写法的详解
  • 深入mysql YEAR() MONTH() DAYOFMONTH()日期函数的详解
  • 深入SQLServer中ISNULL与NULLIF的使用详解
  • 深入C++可见性与生命期的区别详解
  • 深入mysql并发插入优化详解
  • 深入android Unable to resolve target 'android-XX'详解
  • 深入MYSQL字符数字转换的详解
  • 深入SQL Server中定长char(n)与变长varchar(n)的区别详解
  • 深入Windows下的回车是回车换行(rn)还是换行回车(nr)的详解
  • 深入分析NTFS中文件被锁定导致Process.Start失败的详解
  • 深入分析Java内存区域的使用详解
  • Informatica bulk与normal模式的深入详解
  • 深入JAVA对象深度克隆的详解
  • 深入mysql存储过程中表名使用参数传入的详解
  • 深入SQL截取字符串(substring与patindex)的详解
  • 深入Java不可变类型的详解
  • 深入Android开发FAQ的详解
  • 深入第K大数问题以及算法概要的详解
  • 深入SQL SERVER合并相关操作Union,Except,Intersect的详解
  • 深入Main函数中的参数argc,argv的使用详解
  • Docker支持更深入的容器日志分析
  • 关于《深入浅出MFC》
  • Linux有没有什么好的高级的书,我要深入,
  • 深入理解linux内核
  • [100分]有没有关于binutils的深入的资料?或者深入底层的资料?
  • 深入理解PHP内核 TIPI
  • 想深入学习Java应该学习哪些东西
  • 哪位有《JSP深入编程》电子版?
  • 想要深入学习LINUX该学什么?
  • 100分求:哪儿有《深入理解linux内核》可供下哉!
  • 如何深入Linux的内核学习?


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3