C# 异步编程学习(一)
异步 编程 可在 等待 某个 任务 完成时, 避免 线程 的 占用, 但要 想 正确地 实现 编程, 仍然 十分 伤脑筋。
. NET Framework 中, 有三种 不同 的 模型 来 简化 异步 编程。
.NET 1. x 中的 BeginFoo/ EndFoo 方法, 使用 IAsyncResult 和 AsyncCallback 来 传播 结果。
.NET 2. 0 中 基于 事件 的 异步 模式, 使用 BackgroundWorker 和 WebClient 实现。
.NET 4 引入 并由. NET 4. 5 扩展 的 任务 并行 库( TPL)。
(一)APM(异步编程模型)C#版本为1.1
APM异步编程模型最具代表性的特点是:一个异步功能由以Begin开头、End开头的两个方法组成。Begin开头的方法表示启动异步功能的执行,End开头的方法表示等待异步功能执行结束并返回执行结果;
模拟实现:
public class Worker
{
public int A { get; set; }
public int B { get; set; }
private int R { get; set; }
ManualResetEvent et;
public void BeginWork(Action action)
{
et = new ManualResetEvent(false);
new Thread(() =>
{
R = A + B;
Thread.Sleep();
et.Set();
if(null != action)
{
action();
}
}).Start();
} public int EndWork()
{
if(null == et)
{
throw new Exception("调用EndWork前,需要先调用BeginWork");
}
else
{
et.WaitOne();
return R;
} }
}
调用代码:
static void Main(string[] args)
{
Worker w = new Worker();
w.BeginWork(()=> {
Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId,
w.EndWork());
});
Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId);
Console.ReadLine();
}
标准的APM模型如何实现异步编程:
IAsyncResult接口
IAsyncResult接口定义了异步功能的状态,该接口具体属性及含义如下:
// 表示异步操作的状态。
[ComVisible(true)]
public interface IAsyncResult
{
//
// 摘要:
// 获取一个值,该值指示异步操作是否已完成。
//
// 返回结果:
// 如果操作已完成,则为 true;否则为 false。
bool IsCompleted { get; }
//
// 摘要:
// 获取用于等待异步操作完成的 System.Threading.WaitHandle。
//
// 返回结果:
// 用于等待异步操作完成的 System.Threading.WaitHandle。
WaitHandle AsyncWaitHandle { get; }
//
// 摘要:
// 获取一个用户定义的对象,该对象限定或包含有关异步操作的信息。
//
// 返回结果:
// 一个用户定义的对象,限定或包含有关异步操作的信息。
object AsyncState { get; }
//
// 摘要:
// 获取一个值,该值指示异步操作是否同步完成。
//
// 返回结果:
// 如果异步操作同步完成,则为 true;否则为 false。
bool CompletedSynchronously { get; }
}
接口的实现:
public class NewWorker
{
public class WorkerAsyncResult : IAsyncResult
{
AsyncCallback callback;
public WorkerAsyncResult(int a,int b, AsyncCallback callback, object asyncState) {
A = a;
B = b;
state = asyncState;
this.callback = callback;
new Thread(Count).Start(this);
}
public int A { get; set; }
public int B { get; set; } public int R { get; private set; } private object state;
public object AsyncState
{
get
{
return state;
}
}
private ManualResetEvent waitHandle;
public WaitHandle AsyncWaitHandle
{
get
{
if (null == waitHandle)
{
waitHandle = new ManualResetEvent(false);
}
return waitHandle;
}
}
private bool completedSynchronously;
public bool CompletedSynchronously
{
get
{
return completedSynchronously;
}
}
private bool isCompleted;
public bool IsCompleted
{
get
{
return isCompleted;
}
}
private static void Count(object state)
{
var result = state as WorkerAsyncResult;
result.R = result.A + result.B;
Thread.Sleep();
result.completedSynchronously = false;
result.isCompleted = true;
((ManualResetEvent)result.AsyncWaitHandle).Set();
if (result.callback != null)
{
result.callback(result);
}
}
}
public int Num1 { get; set; }
public int Num2 { get; set; } public IAsyncResult BeginWork(AsyncCallback userCallback, object asyncState)
{
IAsyncResult result = new WorkerAsyncResult(Num1,Num2,userCallback, asyncState);
return result;
} public int EndWork(IAsyncResult result)
{
WorkerAsyncResult r = result as WorkerAsyncResult;
r.AsyncWaitHandle.WaitOne();
return r.R;
}
}
调用:
static void Main(string[] args)
{
NewWorker w2 = new NewWorker();
w2.Num1 = ;
w2.Num2 = ;
IAsyncResult r = null;
r = w2.BeginWork((obj) => {
Console.WriteLine("Thread Id:{0},Count:{1}",Thread.CurrentThread.ManagedThreadId,
w2.EndWork(r));
}, null);
Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId);
Console.ReadLine();
}
Delegate异步编程(APM 标准实现)
public class NewWorker2
{
Func<int, int, int> action;
public NewWorker2()
{
action = new Func<int, int, int>(Work);
}
public IAsyncResult BeginWork(AsyncCallback callback, object state)
{
dynamic obj = state;
return action.BeginInvoke(obj.A, obj.B, callback, this);
} public int EndWork(IAsyncResult asyncResult)
{
try
{
return action.EndInvoke(asyncResult);
}
catch (Exception ex)
{
throw ex;
}
} private int Work(int a, int b)
{
Thread.Sleep();
return a + b;
}
}
static void Main(string[] args)
{
NewWorker2 w2 = new NewWorker2();
IAsyncResult r = null;
r = w2.BeginWork((obj) =>
{
Console.WriteLine("Thread Id:{0},Count:{1}", Thread.CurrentThread.ManagedThreadId,
w2.EndWork(r));
}, new { A = , B = });
Console.WriteLine("Thread Id:{0}", Thread.CurrentThread.ManagedThreadId); Console.ReadLine();
}
学习网站:https://blog.csdn.net/nginxs/article/details/77917172
C# 异步编程学习(一)的更多相关文章
- ES6/7 异步编程学习笔记
前言 在ES6的异步函数出现之前,Js实现异步编程只有settimeout.事件监听.回调函数等几种方法 settTmeout 这种方法常用于定时器与动画的功能,因为其本质上其实是浏览器的WebAPI ...
- javascript异步编程学习及实例
所谓异步就是指给定了一串函数调用a,b,c,d,各个函数的执行完结返回过程并不顺序为a->b->c->d(这属于传统的同步编程模式),a,b,c,d调用返回的时机并不确定. 对于js ...
- JavaScript的sleep实现--Javascript异步编程学习
一.原始需求 最近在做百度前端技术学院的练习题,有一个练习是要求遍历一个二叉树,并且做遍历可视化即正在遍历的节点最好颜色不同 二叉树大概长这个样子: 以前序遍历为例啊, 每次访问二叉树的节点加个sle ...
- C#异步编程学习笔记之-async和await(续)
书接上文,本篇主要记录的内容要点:1.针对async和await在实际应用中的使用方式:2.异步方法返回值(有返回值和无返回值)的两种情况: 示例一(无返回值): using System; usin ...
- C#异步编程学习笔记之-async和await
一.异步方法介绍(async和await):如果使用async修饰符将某种方法指定为异步方法,即启用以下两种功能.1.标记的异步方法可以使用await来指定暂停点.await运算符通知编译器异步方法: ...
- .NET 4.5 Task异步编程学习资料
参考资料: 1. http://www.cnblogs.com/heyuquan/archive/2013/04/18/3028044.html
- 我了解到的JavaScript异步编程
一. 一道面试题 前段时间面试,考察比较多的是js异步编程方面的相关知识点,如今,正好轮到自己分享技术,所以想把js异步编程学习下,做个总结. 下面这个demo 概括了大多数面试过程中遇到的问题: f ...
- .net 异步编程async & await关键字的思考
C# 5.0引入了两个关键字 async和await,这两个关键字在很大程度上帮助我们简化了异步编程的实现代码,而且TPL中的task与async和await有很大的关系 思考了一下异步编程中的asy ...
- 多线程编程学习笔记——使用异步IO(一)
接上文 多线程编程学习笔记——使用并发集合(一) 接上文 多线程编程学习笔记——使用并发集合(二) 接上文 多线程编程学习笔记——使用并发集合(三) 假设以下场景,如果在客户端运行程序,最的事情之一是 ...
随机推荐
- 解决Android单个dex文件不能超过65535个方法问题
一.找坑:谷歌规定单个dex文件中的方法不能超过65536的限制 我们编写项目过程中在工程的lib文件夹下引用的第三方插件jar包太多或者项目过大,编译运行时就有可能报出com.android.dex ...
- [ Tools ] [ MobaXterm ] [ SSH ] [ Linux ] export and import saved session
How to export MobaXterm sessions to another computer? https://superuser.com/questions/858973/how-to- ...
- 转/ C# 托管资源和非托管资源
原文 对于这两个一直就是模模糊糊的,半知零解 托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源.托管资源的回收工作是不需要人工干预的,由.NET运行库在合适时调用垃圾回收器 ...
- 【Oracle】非RMAN恢复数据文件、控制文件
实验环境:OEL 5.6 oracle 11g(11.2.0.4.0) 注意: system表空间数据文件不能在线recover,需要启动到mount状态再recover: undo表空间数据文件可以 ...
- 将JavaBean对象/List或Set或Map对象转成JSON方式
一.通过Struts2插件包(即使用Struts框架)自动生成JSON文本 二.使用第三方工具,将JavaBean对象/List或Set或Map对象转成JSON 准备导入第三方jar包: >c ...
- C语言基础 (9) 数组指针
复习 只要把地址拿到就能这么操作.. (这里是合法的地址,不是野指针) 只有定义变量后,此变量的地址才是合法的地址 野指针就是保存没有意义地址的指针变量 操作野指针变量本身不会有任何问题 操作野指针所 ...
- C++ STL-stack使用详解
stack 类是容器适配器,它给予程序员栈的功能--特别是 FILO (先进后出)数据结构. 该类模板表现为底层容器的包装器--只提供特定函数集合.栈从被称作栈顶的容器尾部推弹元素. 一:头文件 #i ...
- 2、Ansible配置文件详解
0.配置文件 两个核心文件:ansible.cfg和hosts文件,默认都存放在/etc/ansible目录下. ansible.cfg:主要设置一些ansible初始化的信息,比如日志存放路径.模块 ...
- 1、认识和安装MongoDB
MongoDB简介:MongoDB是一个基于分布式文件存储的数据库,由C++语言编写.目的是为WEB应用提供扩展的高性能的数据存储解决方案.MongoDB是一个介于关系型数据库和非关系型数据库之间的产 ...
- google浏览器中 查看记住的账号和密码
对于一个有“健忘症”的人来说,密码形同虚设..设置了就忘记,每次登陆都要重新设置密码... 然后,无意中发现,谷歌浏览器点过一次记住密码后,竟然可以明文查看账号和密码!! 步骤: 1.打开谷歌浏览器, ...