多线程、异步编程、并行编程 (Multi-Threading, async, await, Task, Task<TResult>)

创建时间:
2014-02-20 23:26
最近更新:
2018-08-03 00:31

相关

  • 同步 (lock) - 详见本站专文
  • 异步 / 并发 / 多线程 - 详见本站专文
  • System.Threading 命名空间 (进程、线程) - 详见本站专文

Resource - MSDN - Entrance

  1. .NET Framework 中的并行处理和并发 - Entrance
  2. .NET 中的并行处理、并发和异步编程
  3. 异步概述
  4. .NET 中的并行编程
  5. 托管线程处理
  6. 线程处理 (C#)

Resource - MSDN

  1. 基于任务的异步模式 (TAP)
  2. 任务并行 (任务并行库, Task Parallel Library, TPL)
  3. SynchronizationContext 综述
  1. Thread Synchronization / 线程同步 (C#) - 以下各节中描述的功能和类可用于同步访问多线程应用程序中的资源。 在应用程序中使用多线程的好处之一是每个线程都可以异步方式执行。对于 Windows 应用程序,这允许在后台执行耗时的任务,同时应用程序窗口和控件保持响应状态。对于服务器应用程序,多线程处理提供了用不同线程处理每个传入请求的能力。否则,在满足上一个请求之前,将无法处理任何新请求。 然而,线程的异步性质意味着必须协调对文件句柄、网络连接和内存等资源的访问。否则,两个或多个线程可能在同一时间访问同一资源,且不能感知对方的操作。结果是不可预知的数据损坏。 对于针对整数数据类型的简单操作,可以通过 Interlocked 类的成员完成同步处理线程。对于其他所有数据类型和非线程安全资源,只有使用本主题中的构造才能安全地执行多线程处理。

Resource

  1. .NET 异步编程总结
  2. .NET 中的异步编程
  3. 看 StackOverflow 大牛如何回答何时在 ASP.NET 中使用异步控制器
  4. Multi-Threading in ASP.NET
  5. 异步编程 系列博文
  6. 详解 .NET 异步
  7. 详解 ASP.NET 异步
  8. ASP.NET MVC4 异步方法
  9. C# 5.0 异步编程 (async/await)

async & await

async 和 await 是一对标记符,可以用来标记当一个任务 (线程) 完成后将返回到哪里。
这里有三点需要注意的地方:

  1. async 和 await 总是成对出现,不能单独使用。
  2. async 是标记方法的,这个标记只是指示出该方法中将包含 await 关键字。
  3. await 关键字标记了任务执行结束后需要返回到的位置,所以你常常会将该关键字与 Task 类联用。

async & await - Resource on MSDN

  1. 使用 async 和 await 的异步编程 (MSDN 上的入口页面)
  2. async (C# 参考)
  3. await (C# 参考)
  4. async & await 异步编程中的最佳做法

async & await - Resource

  1. async & await 原理
  2. 关于 async 与 await 的 FAQ - 译文
  3. 关于 async 与 await 的 FAQ - 原文
  4. 关于 async 与 await 的 FAQ
  5. async & await 简单入门
  6. async、await 在 ASP.NET MVC 中之线程死锁的故事
  7. 探索 C#之 async、await 剖析

async & await - Resource - JavaScript

  1. 精读 《async / await 是把双刃剑》

2011-10 MSDN 上三篇介绍 async 和 await 的优秀文章

推荐阅读顺序依次为:

  1. 通过新的 Visual Studio Async CTP 更轻松地进行异步编程
  2. 通过 Await 暂停和播放
  3. 了解 Async 和 Await 的成本

Task 类

表示一个异步操作。
http://msdn.microsoft.com/zh-cn/library/system.threading.tasks.task

继承层次结构

System.Object
System.Threading.Tasks.Task

Syntax

public class Task : IAsyncResult, IDisposable

Task<TResult> 类

表示一个可以返回值的异步操作。
http://msdn.microsoft.com/zh-cn/library/dd321424

继承层次结构

System.Object
System.Threading.Tasks.Task
System.Threading.Tasks.Task<TResult>

Syntax

public class Task<TResult> : Task

测试 async, await, Task 的行为

using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
	static void Main(string[] args)
	{
		Console.Write(1);
		//测试时,总是仅执行1个而注释其它:
		//Method0();//Result: 135642
		//Method1();//Result: 134256
		//Method2();//Result: 132564
		Method3();//Result: 134256
		//测试记录:以上所有Method总是在5与6之间停顿3秒。
		Console.Write(2);
		Console.ReadKey();
	}
	//无async/await/Task:
	public static void Method0()
	{
		Console.Write(3);
		LongTask();
		Console.Write(4);
	}
	//Method1比Method0仅多了Task。
	public static void Method1()
	{
		Console.Write(3);
		Task.Run(new Action(LongTask));//仅需Task.Run(),即可将LongTask置于另一线程,且在原有线程全部执行完毕之后再执行。
		Console.Write(4);//Task.Run()并不影响这一行,而await会影响该async方法内的剩余代码。
	}
	//Method2比Method1仅多了async与await两个关键字。
	public static async void Method2()
	{
		Console.Write(3);
		await Task.Run(new Action(LongTask));//await导致该async方法内的剩余代码置于另一线程,且在原有线程全部执行完毕之后再执行。
		Console.Write(4);//注意await与Task.Run()的区别。
	}
	//Method3比Method2仅少了await关键字。
	//Method3比Method1仅多了async关键字,二者执行结果相同。
	//测试记录:await只能用于async方法中,否则无法通过编译;但async方法中可没有await,此时仅警告但仍可通过编译。
	public static async void Method3()
	{
		Console.Write(3);
		Task.Run(new Action(LongTask));
		Console.Write(4);
	}
	public static void LongTask()
	{
		Console.Write(5);
		Thread.Sleep(3000);
		Console.Write(6);
	}
}