异步编程系列(Thread、Task、async/await、ajax等)

 

 

术语:

APM    异步编程模型,Asynchronous Programming Model

EAP    基于事件的异步编程模式,Event-based Asynchronous Pattern

TAP    基于任务的异步编程模式,Task-based Asynchronous Pattern

TPL    任务并行库,Task Parallel Library

 

    经过一番努力,我写的异步编程系列也算有头有尾,现在我给这个系列整个目录和做个简单介绍。

“概要 + 目录”整理

    C#语言是微软于2000年发布,基于.NET Framewrok框架的、面向对象的高级语言。经过近十三年的发展,经历了5次大的升级,目前最新版本为C#5.0(对应于.NET Framework 4.5)。其中每个版本发布都是有一个“主题”。即:C#1.0托管代码→C#2.0泛型→C#3.0LINQC#4.0动态语言→C#5.0异步编程。这系列既是针对“异步编程”所写。

C#版本

.NET 版本

Visual Studio 版本

特性描述

C# 1.0

.NET 1.0/1.1

VS 2002/2003

C#的第一个正式发行版本。微软的团队从无到有创造了一种语言,专门为.NET编程提供支持

 

 

 

C# 2.0

.NET 2.0

 

 

 

VS 2005

C#语言开始支持泛型,.NET Framework 2.0新增了支持泛型的库

.NET 3.0

新增了一套API来支持分布式通信(Windows Communication Foundation WCF)、富客户端表示(Windows Presentation Foundation)、工作流(Windows WorkflowWF)以及Web身份验证(Cardspaces

C# 3.0

.NET 3.5

VS 2008

添加了对LINQ的支持,对用于集合编程的API进行了大幅改进。.NET Framework 3.5对原有的API进行了扩展,从而支持了LINQ   

C# 4.0

.NET 4.0

VS 2010

添加了动态类型(dynamic)的支持,引入了新的轻量级线程同步基元及新的异步编程类库TPL

C# 5.0

.NET 4.5

VS 2012

改进并扩展了.NET4.0中引入的TPL类库,并引入asyncawait关键字轻松构建异步方法。

 

1. 异步编程基础

资料整理路线:线程----线程池----线程同步----并行任务----三种异步编程模型。首先了解最基础的线程(Thread),再进一步明白线程管理器(ThreadPool)。因为多个工作项之间可能出现并行运行,会造成对共享资源的访问问题,所以引入线程同步基元来让共享资源得到合理使用。最后介绍.NET4.0新引入并在.NET4.5中得到优化和扩展的TPL(任务并行库),并结合C# 5.0中新引入的asyncawait关键字轻松构建异步方法。详细如下:

异步编程:线程概述及使用

异步编程:使用线程池管理线程

异步编程:线程同步基元对象

异步编程:轻量级线程同步基元对象

异步编程:.NET4.5 数据并行

异步编程:异步编程模型 (APM)

异步编程:基于事件的异步编程模式(EAP)

异步编程:.NET 4.5 基于任务的异步编程模型(TAP)

 

CancellationToken

多线程之取消令牌(CancellationToken)

在C#中使用 CancellationToken 处理异步任务

.net core优雅退出

获取应用退出 CancellationToken

.NET Core使用 CancellationToken 取消API请求

 

 

(译).NET4.X 并行任务中Task.Start()的FAQ

(译).NET4.X并行任务Task需要释放吗?

Task.CompletedTask和Task.Result小记

IAsyncDisposable接口

Thread、ThreadPool、Task、Parallel、Async和Await基本用法、区别以及弊端

新接口IAsyncDisposable

C#异步迭代 IAsyncEnumerable 应用

 

NET问答: using 和 await using 有什么不同?

并行中的分区Partitioner

Task.Factory.StartNew 和 Task.Factory.FromAsync 有什么区别?

Task.Factory.StartNew 和 Task.Run 到底有什么区别?(一般情况,都使用Task.Run)

TaskExtensions.Unwrap 方法

Unwrap 解包,会把嵌套的Task<Task>或者Task<Task<T>>的结果提取出来。(相当于await result)

Task.Factory.StartNew和Task.Run区别之一就有Task.Run会自动执行Unwrap操作

AsyncEx - async/await 的辅助库

C#ThreadLocal和AsyncLocal

 

  活锁与死锁

    #、加锁后超时释放,且超时要有一定的随机性

    #、加锁按照一定的顺序规则

 

ExecutionContext执行上下文   

.NET AsyncLocal 使用方法

#、AsyncLocal 的实际数据存储在 ExecutionContext 中,而 ExecutionContext 作为线程的私有字段与线程绑定,在线程会发生切换的地方,runtime 会将切换前的 ExecutionContext 保存起来,切换后再恢复到新线程上。

#、分析 HttpContextAccessor 的实现原理

#、ValueAccessor 模式,在abp中也使用过Accessor设计

浅析 .NET 中 AsyncLocal 的实现原理

#、在.NET 中,每个线程都关联着一个执行上下文(execution context)。可以通过Thread.CurrentThread.ExecutionContext属性进行访问,或者通过 ExecutionContext.Capture() 获取(前者的实现) 。

#、AsyncLocal 最终就是把数据保存在 ExecutionContext 上的

 

  线程安全

  .NET 线程安全的集合

 System.Collections.Concurrent(BlockingCollection<T>、ConcurrentBag<T>、ConcurrentDictionary<TKey, TValue>、ConcurrentQueue<T>、ConcurrentStack<T> )

 

                 

 

2. async\await 使用注意事项

(译)关于async与await的FAQ

[译]async/await中阻塞死锁

async中必须始终返回Task(@Ron.liang)

此文因在async返回void,在基于任务的异步模式(TAP)并不知道异步任务的状态,当 this.context.Update 执行完成后,发现挂载在内存中的连接已经没有使用,就执行了回收;实际上,此时程序还没有执行完成,但是 TAP 并不知道,所以它不会去阻止这个回收的过程(使用标记),释放 DbContext 后抛出异常 

Task.Run(async () => await MethodAsync()).Result 和 MethodAsync().Result 之间有什么区别吗?

.net core针对async ()=>的安全处理     (Action 改为 Func<Task?>)

 

 

Parallel.ForEach和异步的await

  注意:await会导致parallel提前结束,并标示完成状态,但实际上在await后面的代码都没有执行了

NET问答: 多个 await 和 Task.WaitAll 是等价的吗?

为什么async/await方法不能有lock或Monitor

如何保证执行异步方法时不会遗漏 await 关键字

 

 

 

3. 示例:构建Async同步基元

TPL提供同步基元,但这只是提供TPL的应用思路,不推荐将这些同步基元应用于项目中。

(译)构建Async同步基元,Part 1 AsyncManualResetEvent

(译)构建Async同步基元,Part 2 AsyncAutoResetEvent

(译)构建Async同步基元,Part 3 AsyncCountdownEvent

(译)构建Async同步基元,Part 4 AsyncBarrier

(译)构建Async同步基元,Part 5 AsyncSemaphore

(译)构建Async同步基元,Part 6 AsyncLock

(译)构建Async同步基元,Part 7 AsyncReaderWriterLock

 

4. 前端中的异步

触碰jQuery:AJAX异步详解

使用jQuery.form插件,实现完美的表单异步提交

 

5. 持续更新……

 

 “加关注”更快获得持续更新。

喜欢本系列博文的园友还请多多推荐image(*^_^*)……感谢大家支持!

 

 

 

推荐阅读:

高性能IO模型浅析

为什么要放弃使用Thread.Sleep

 

 

 

 

在.NET 中,每个线程都关联着一个 执行上下文(execution context) 。 可以通过Thread.CurrentThread.ExecutionContext 属性进行访问,或者通过 ExecutionContext.Capture() 获取(前者的实现) 。
AsyncLocal 最终就是把数据保存在 ExecutionContext 上的
 
posted on 2013-04-26 21:14  滴答的雨  阅读(24035)  评论(123编辑  收藏  举报