C# Async

asyncawait两个关键字配合使用,可以方便的进行异步编程。我们通过一个实例体会一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class TestAsync
{
public static void Main(string[] args)
{

Async1();
Console.ReadKey();
}

public static async void Async1()
{

Console.WriteLine(string.Format("Async1 Start {0}", Thread.CurrentThread.ManagedThreadId));
var t = Async2();
Console.WriteLine(string.Format("Async1 Independent {0}", Thread.CurrentThread.ManagedThreadId));
var tr = await t;
Console.WriteLine(string.Format("Async1 Complete {0}", Thread.CurrentThread.ManagedThreadId));
return;
}

public static async Task<int> Async2()
{

Console.WriteLine(string.Format("Async2 Start {0}", Thread.CurrentThread.ManagedThreadId));
var t = Async3();
Console.WriteLine(string.Format("Async2 Independent {0}", Thread.CurrentThread.ManagedThreadId));
var tr = await t;
Console.WriteLine(string.Format("Async2 Complete {0}", Thread.CurrentThread.ManagedThreadId));
return tr;
}

public static async Task<int> Async3()
{

Console.WriteLine(string.Format("Async3 Start {0}", Thread.CurrentThread.ManagedThreadId));
var t = Task.Run(() =>
{
Console.WriteLine("New Task! Thread: {0} Start", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
Console.WriteLine("New Task! Thread: {0} End", Thread.CurrentThread.ManagedThreadId);
return 1;
});
Console.WriteLine(string.Format("Async3 Independent {0}", Thread.CurrentThread.ManagedThreadId));
var tr = await t;
Console.WriteLine(string.Format("Async3 Complete {0}", Thread.CurrentThread.ManagedThreadId));
return tr;
}
}

上面的例子中,调用关系是Async1()->Async2()->Async3()->New Task。运行的结果为:
刚刚开始
刚刚开始
五秒钟后
五秒钟后
可见:

  • 除非手动新建进程(上例中的Task.Run),仅仅调用async方法是不会马上新建进程的。
  • 当函数运行到await时,如果await的Task没有完成,会返回到函数调用方继续执行。当await的Task完成时,会从线程池中激活一个线程,并恢复到await当时的现场(即为上例中的线程7)。原话是:

When the Called() is done then a thread from the ThreadPool (can be any thread) will return to Caller() in its previous context and continue execution.

C# 异步编程相关资料