并发编程概念

并发编程概念

并发

同时做多件事情。
并发编程有:多线程编程、异步编程、响应式编程。并行处理是多线程的一种。

多线程编程

并发的一种形式,它采用多个线程来执行程序。并行处理是多线程的一种。

并行处理:把正在执行的大量的任务分割成小块,分配给多个同时运行的线程。

异步编程

并发的一种形式,它采用 future 模式或回调(callback)机制,以避免产生不必要的线程。

异步编程的核心理念是异步操作:启动了的操作将会在一段时间后完成。这个操作正在执行时,不会阻塞原来的线程。启动了这个操作的线程,可以继续执行其他任务。当操作完成时,会通知它的 future,或者调用回调函数,以便让程序知道操作已经结束。

现代的异步 .NET 程序使用两个关键字: asyncawaitasync 关键字加在方法声明上,它的主要目的是使方法内的 await 关键字生效(为了保持向后兼容,同时引入了这两个关键字)。如果 async 方法有返回值,应返回 Task<T> ;如果没有返回值,应返回 Task 这些task 类型相当于 future,用来在异步方法结束时通知主程序。

await 关键字是针对 Task 的,确切的说是针对所有遵循特定模式的 awaitable 类型。

注意: 不要用 void 作为 async 方法的返回类型! async 方法可以返回 void ,但是这
仅限于编写事件处理程序。一个普通的 async 方法如果没有返回值,要返回
Task ,而不是 void 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/// <summary>
/// async事件,返回值为void,特例
/// </summary>
private async void button1_Click(object sender, EventArgs e)
{
await DoSomethingAsync(); //等待异步执行完成再执行后面的语句,但界面不会阻塞
label1.Text = "Done!";
}

/// <summary>
/// 普通事件,返回值为void
/// </summary>
private void button1_Click(object sender, EventArgs e)
{
DoSomethingAsync(); //直接返回,先执行后面语句!
lablabel1.Text = "Done!";
}

注意:关于异步方法,还有一条重要的准则:你一旦在代码中使用了异步,最好一直使用。调用异步方法时,应该(在调用结束时)用 await 等待它返回的 task 对象。一定要避免使用 Task.WaitTask<T>.Result 方法,因为它们会导致死锁。参考一下下面这个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

async Task WaitAsync()
{
// 这里 awati 会捕获当前上下文……
await Task.Delay(TimeSpan.FromSeconds(1)); //.ConfigureAwait(false);加上这个就没问题
// ……这里会试图用上面捕获的上下文继续执行
}

void Deadlock()
{
// 开始延迟
Task task = WaitAsync();
// 同步程序块,正在等待异步方法完成
task.Wait();
}

ConfigureAwait 的说明是:试图继续回夺取的原始上下文,则为 true;否则为 false

响应式编程

一种声明式的编程模式,程序在该模式中对事件做出响应。

响应式编程与异步编程非常类似,不过它是基于异步事件(asynchronous event)的,而不是异步操作(asynchronous operation)。异步事件可以没有一个实际的“开始”,可以在任何时间发生,并且可以发生多次,例如用户输入。

参考