对于异步,相信大家都不十分陌生。准确点来说就是方法执行后立即返回,待到执行完毕会进行通知。就是当一个任务在执行的时候,尤其是需要耗费很长的时间进行处理的任务,如果利用单线程进行操作的话,势必造成界面的阻塞;而利用异步方式,则不会出现这种情况。 区别于同步处理,可以说阻塞的异步其实就相当于同步。

同步方式的实现

先来看一个同步的例子:

假设现在我们需要导入文本文件的内容,然后对文件内容做处理。那么这就需要分为两步来进行,第一步是导入文本内容,我们利用函数A表示;第二部就是处理文本,我们利用函数B来表示。假设现在A不执行完,B不能进行。而且由于文本内容非常大,导入需要十几到几十分钟不等,那么我们得提示用户导入进度,这里就涉及到了界面交互问题。利用同步方式来做,效果如何呢?首先请看运行效果:

#region 第一步:加载进入内存private void ReadIntoMemory(){if (String.IsNullOrEmpty(fileName)){MessageBox.Show("文件名不能为空!");return;}string result;long mainCount = 0;using (StreamReader sr = new StreamReader(fileName, Encoding.Default)){while ((result = sr.ReadLine()) != null){mainCount++;recordList.Add(result); //添加记录到List中存储,以便在下一步进行处理。double statusResult = (double)mainCount / (double)totalCount;lblCurrentRecords.Text = mainCount.ToString();lblStatus.Text = statusResult.ToString("p");pbMain.Value = Int32.Parse((Math.Floor(statusResult)*100).ToString());}}}#endregion#region 第二步:处理数据private void ProcessRecords(){if (recordList ==null){throw new Exception("数据不存在!");}if (recordList.Count==0){return;}int childCount = 0;int recordCount = recordList.Count;for (int i = 0; i < recordCount; i++){string thisRecord=recordList[i];if (String.IsNullOrEmpty(thisRecord) || !thisRecord.Contains(",")){return;}string[] result = thisRecord.Split(',');ListViewItem lvi = new ListViewItem(result[0]);for (int j = 1; j < result.Length; j++){lvi.SubItems.Add(result[j]);}listItem.Add(lvi);childCount++;double percentage = (double)childCount / (double)recordCount;pbChild.Value = Int32.Parse((Math.Floor(percentage) * 100).ToString());}}#endregion

#region 开始进行处理private void btnLoad_Click(object sender, EventArgs e){GetTotalRecordNum(); //得到总条数
ReadIntoMemory();ProcessRecords();}#endregion

我们是直接顺序运行的。之所以出现上面的情况,最主要就是界面处理和后台处理均糅合在了同一个线程之中,这样当后台进行数据处理的时候,会造成前台UI线程无法更新UI。要解决这种情况,当然是使用异步方式类处理:

那么在.net编程中,有哪几种模式可以实现异步呢?

4种异步方式

  1. ThreadPool.QueueUserworkItem实现
  2. APM模式(就是BeginXXX和EndXXX成对出现。)
  3. EAP模式(就是Event based, 准确说来就是任务在处理中或者处理完成,会抛出事件)
  4. Task

上面总共4种方式中,其中在.net 2.0中常用的是(1),(2),(3),而在.net 4.0中支持的是(4),注意(4)在.net 2.0中是不能使用的,因为不存在。

首先来说说ThreadPool.QueueUserWorkItem方式,也是最简单的一种方式。

系统将需要运行的任务放到线程池中,那么线程池中的任务就有机会通过并行的方式进行运行。

其次来说说APM模式

这种模式非常常见,当然也是Jeff Richter极力推荐的一种方式。同时我也是这种模式的粉丝。这种模式的使用非常简单,就是利用Begin***的方式将需要进行异步处理的任务放入,然后通过End***的方式来接受方法的返回值。同时在Begin***和End***任务进行的过程中,如果涉及到界面UI的更新的时候,我们完全可以加入通知的功能。

在Begin***和End***进行处理的时候,传递的是IAsyncResult对象,这种对象在Begin***中会承载一个委托对象,然后在End***中进行还原并得到返回值。

如果你在设计的时候,需要有多个方法用到异步,并且想控制他们的运行顺序,请参考ManualResetEvent 和 AutoResetEvent方法,他们均是通过设置信号量来进行同步的。

下面来看一个例子:

假设现在我们需要导入文本文件的内容,然后对文件内容做处理。那么这就需要分为两步来进行,第一步是导入文本内容,我们利用函数A表示;第二部就是处理文本,我们利用函数B来表示。假设现在A不执行完,B不能进行。而且由于文本内容非常大,导入需要十几到几十分钟不等,那么我们得提示用户导入进度,这里就涉及到了界面交互问题。利用APM模式如何来做呢?首先请看运行效果:

#region 典型的APM处理方式,利用Action作为无参无返回值的委托private void BeginReadIntoMemory(){Action action = new Action(ReadIntoMemory);action.BeginInvoke(new AsyncCallback(EndReadIntoMemory), action);}private void EndReadIntoMemory(IAsyncResult iar){Action action = (Action)iar.AsyncState;action.EndInvoke(iar);}private void BeginProcessRecords(){Action action = new Action(ProcessRecords);action.BeginInvoke(new AsyncCallback(EndProcessRecords), action);}private void EndProcessRecords(IAsyncResult iar){Action action = (Action)iar.AsyncState;action.EndInvoke(iar);}#endregion

#region 开始进行处理,需要通过ManualResetEvent设置xinhaoilang的方式进行同步private void btnLoad_Click(object sender, EventArgs e){GetTotalRecordNum(); //得到总条数
BeginReadIntoMemory(); //读取数据到内存BeginProcessRecords(); //处理数据内容
        }#endregion

在上面的代码段中,APM模式的处理方式很明显

然后来说说EAP模式

这种模式也很常见,准确来说就是在系统中通过申明委托事件,然后在执行过程中或者执行完毕后抛出事件。最常见的莫过于WebClient类的DownloadStringCompleted事件,这里我们将使用BackgroundWorker来进行讲解,虽然它本身就能够实现异步操作。在这里,我们只是用到了一个从文本中读取大数据量到内存的操作。图示如下:

转自【http://www.cnblogs.com/scy251147/archive/2012/03/03/2378477.html】

转载于:https://www.cnblogs.com/xiashenbin/p/3210335.html

.NET 实现异步处理的集中方式相关推荐

  1. 异步编程的实现方式以及区别

    1.异步编程的实现方式? JavaScript中的异步机制可以分为以下几种: ━ 回调函数的方式,使用回调函数的方式有一个缺点是,多个回调函数嵌套的时候会造成回调地狱,上下两层的回调函数间的代码耦合度 ...

  2. tornado异步非阻塞实现方式

    目录 tornado异步非阻塞实现方式 1.多线程 2.老版协程 3.新版协程 实验 1.完全阻塞,同步代码 2.老版本协程 3新版本协程 4 多线程+新版协程,线程函数失效 5.线程+不声明异步,可 ...

  3. 【Python进阶学习】gRPC在Python的异步非阻塞实现方式

    gRPC在Python的异步非阻塞实现方式 前言 问题&分析 问题阐述 原因分析 解决方案 服务端 原服务端实现方式 aio的服务端实现方式: 客户端 异步非阻塞方式 同步阻塞方式 性能优化效 ...

  4. dva中dispatch函数实现异步回调函数的方式

    #关于 dva中dispatch函数实现异步回调函数的方式 1.通过promise函数实现 这里先给出index.js 和modal模块的实现 services模块不需要做处理 //index.jsi ...

  5. STL库(C++11)提供的异步执行方法的方式

    在进行并发编程的时候难免会遇到异步执行时候,现代C++标准库提供了几种异步执行的方式,本文收集整理了一下,以备将来翻阅. Thread方式 Thread 是STL提供的一种快捷创建线程的方式,极大方便 ...

  6. C#异步编程的实现方式(1)——异步委托

    异步的实现即多线程,一种简单的方式就是创建一个委托,然后异步调用它. .Net Framework已经为我们提供了委托的异步调用方法.下面介绍三种使用委托实现异步的方法. 1.投票(IsComplet ...

  7. [转]C#异步编程的实现方式(1)——异步委托

    异步的实现即多线程,一种简单的方式就是创建一个委托,然后异步调用它. .Net Framework已经为我们提供了委托的异步调用方法.下面介绍三种使用委托实现异步的方法. 1.投票(IsComplet ...

  8. ajax_异步交互-get/post方式

    Ajax的异步交互: 客户端向服务器端发送请求,直到服务器端进行响应,这个过程中,用户可以做任何其他事情(不等). 实现Ajax的异步交互步骤(举例说明): get方式: 1.创建XMLHttpReq ...

  9. C#异步编程的实现方式(4)——Task任务

    .Net Framework 4.0新增了一个System.Threading.Tasks命名空间,它包含的类提供了任务的相关操作.使用任务不仅可以获得一个抽象层,还能对底层线程进行很多统一的控制操作 ...

  10. SpringBoot2.0 基础案例(04):定时任务和异步任务的使用方式

    一.定时任务 1.基本概念 按照指定时间执行的程序. 2.使用场景 数据分析 数据清理 系统服务监控 二.同步和异步 1.基本概念 同步调用 程序按照代码顺序依次执行,每一行程序都必须等待上一行程序执 ...

最新文章

  1. 创建用户的SHELL小脚本
  2. tensorflow 卷积、反卷积形式的去噪自编码器
  3. FFmpeg中的日志以及avio实现对文件的读写功能
  4. 玩英雄联盟手游,谁才是新手最喜欢的英雄?无极剑圣还是吗?
  5. apache 目录网站显示indexs
  6. 反思O2O演化的三个时代,大数据与智能化才是未来所在
  7. linux可以http安装么,Linux 5下 http的安装
  8. Python 面向对象 实例方法 属性 (上)
  9. PyQt5入门——手把手教你配置环境,快速上手GUI程序开发(Anaconda+PyCharm+Qt Designer+pyuic)
  10. Django ORM中原生JSONField的使用方法
  11. 百万 Go TCP 连接的思考: epoll方式减少资源占用
  12. 配置Hadoop开发环境(Eclipse)
  13. 网易考拉向欧洲市场投入220亿,能掀起多大波澜?
  14. MATLAB通信系统建模
  15. python的ols_工具方法 | 6行代码教你用Python做OLS回归(内附CFPS实例)
  16. Elasticsearch 7.1API 文档翻译
  17. position属性与z-index属性详解,如何比较z-index值确定覆盖关系,为何z-index属性不生效。
  18. 全国计算机一级上表格怎么做,全国计算机一级考试word表格制作(2003版)
  19. 40 How Many Numbers Are Smaller Than the Current Number
  20. 数据挖掘:FP-Growth算法 (Python实现)

热门文章

  1. Noise,Error,wighted pocket Algorithm
  2. 一篇通俗易懂的讲解OpenGL ES的文章
  3. About_php_封装函数
  4. JAVA 入门PDF
  5. hadoop学习笔记(五):java api 操作hdfs
  6. 构建之法第四章学习心得
  7. linux 学习6 软件包管理 资料链接
  8. 重构 阅读心得(转)
  9. Win64下通过JNI(C++)创建jvm
  10. .NET组件和COM组件之间的相互操作方法