.NET 实现异步处理的集中方式
对于异步,相信大家都不十分陌生。准确点来说就是方法执行后立即返回,待到执行完毕会进行通知。就是当一个任务在执行的时候,尤其是需要耗费很长的时间进行处理的任务,如果利用单线程进行操作的话,势必造成界面的阻塞;而利用异步方式,则不会出现这种情况。 区别于同步处理,可以说阻塞的异步其实就相当于同步。
同步方式的实现
先来看一个同步的例子:
假设现在我们需要导入文本文件的内容,然后对文件内容做处理。那么这就需要分为两步来进行,第一步是导入文本内容,我们利用函数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种异步方式
- ThreadPool.QueueUserworkItem实现
- APM模式(就是BeginXXX和EndXXX成对出现。)
- EAP模式(就是Event based, 准确说来就是任务在处理中或者处理完成,会抛出事件)
- 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.异步编程的实现方式? JavaScript中的异步机制可以分为以下几种: ━ 回调函数的方式,使用回调函数的方式有一个缺点是,多个回调函数嵌套的时候会造成回调地狱,上下两层的回调函数间的代码耦合度 ...
- tornado异步非阻塞实现方式
目录 tornado异步非阻塞实现方式 1.多线程 2.老版协程 3.新版协程 实验 1.完全阻塞,同步代码 2.老版本协程 3新版本协程 4 多线程+新版协程,线程函数失效 5.线程+不声明异步,可 ...
- 【Python进阶学习】gRPC在Python的异步非阻塞实现方式
gRPC在Python的异步非阻塞实现方式 前言 问题&分析 问题阐述 原因分析 解决方案 服务端 原服务端实现方式 aio的服务端实现方式: 客户端 异步非阻塞方式 同步阻塞方式 性能优化效 ...
- dva中dispatch函数实现异步回调函数的方式
#关于 dva中dispatch函数实现异步回调函数的方式 1.通过promise函数实现 这里先给出index.js 和modal模块的实现 services模块不需要做处理 //index.jsi ...
- STL库(C++11)提供的异步执行方法的方式
在进行并发编程的时候难免会遇到异步执行时候,现代C++标准库提供了几种异步执行的方式,本文收集整理了一下,以备将来翻阅. Thread方式 Thread 是STL提供的一种快捷创建线程的方式,极大方便 ...
- C#异步编程的实现方式(1)——异步委托
异步的实现即多线程,一种简单的方式就是创建一个委托,然后异步调用它. .Net Framework已经为我们提供了委托的异步调用方法.下面介绍三种使用委托实现异步的方法. 1.投票(IsComplet ...
- [转]C#异步编程的实现方式(1)——异步委托
异步的实现即多线程,一种简单的方式就是创建一个委托,然后异步调用它. .Net Framework已经为我们提供了委托的异步调用方法.下面介绍三种使用委托实现异步的方法. 1.投票(IsComplet ...
- ajax_异步交互-get/post方式
Ajax的异步交互: 客户端向服务器端发送请求,直到服务器端进行响应,这个过程中,用户可以做任何其他事情(不等). 实现Ajax的异步交互步骤(举例说明): get方式: 1.创建XMLHttpReq ...
- C#异步编程的实现方式(4)——Task任务
.Net Framework 4.0新增了一个System.Threading.Tasks命名空间,它包含的类提供了任务的相关操作.使用任务不仅可以获得一个抽象层,还能对底层线程进行很多统一的控制操作 ...
- SpringBoot2.0 基础案例(04):定时任务和异步任务的使用方式
一.定时任务 1.基本概念 按照指定时间执行的程序. 2.使用场景 数据分析 数据清理 系统服务监控 二.同步和异步 1.基本概念 同步调用 程序按照代码顺序依次执行,每一行程序都必须等待上一行程序执 ...
最新文章
- 创建用户的SHELL小脚本
- tensorflow 卷积、反卷积形式的去噪自编码器
- FFmpeg中的日志以及avio实现对文件的读写功能
- 玩英雄联盟手游,谁才是新手最喜欢的英雄?无极剑圣还是吗?
- apache 目录网站显示indexs
- 反思O2O演化的三个时代,大数据与智能化才是未来所在
- linux可以http安装么,Linux 5下 http的安装
- Python 面向对象 实例方法 属性 (上)
- PyQt5入门——手把手教你配置环境,快速上手GUI程序开发(Anaconda+PyCharm+Qt Designer+pyuic)
- Django ORM中原生JSONField的使用方法
- 百万 Go TCP 连接的思考: epoll方式减少资源占用
- 配置Hadoop开发环境(Eclipse)
- 网易考拉向欧洲市场投入220亿,能掀起多大波澜?
- MATLAB通信系统建模
- python的ols_工具方法 | 6行代码教你用Python做OLS回归(内附CFPS实例)
- Elasticsearch 7.1API 文档翻译
- position属性与z-index属性详解,如何比较z-index值确定覆盖关系,为何z-index属性不生效。
- 全国计算机一级上表格怎么做,全国计算机一级考试word表格制作(2003版)
- 40 How Many Numbers Are Smaller Than the Current Number
- 数据挖掘:FP-Growth算法 (Python实现)