Async和Await是在.NET Framework 4.5,C# 5.0之后出现的,它的出现为我们编写异步的程序,提供了不少的便利。
执行顺序
static void Main(string[] args)
{
Console.WriteLine("第1步");
MyTask.Sequence();
Console.WriteLine("第3步");
Console.ReadKey();
}
public class MyTask
{
public static async void Sequence()
{
Console.WriteLine("第2步");
await Task.Run(() =>
{
Thread.Sleep(500);
Console.WriteLine("第4步");
});
Console.WriteLine("第5步");
}
}
运行结果:
从运行的结果来看,主线程在遇到Task的时候,会启动子线程执行任务,然后主线程继续执行,然后当遇到await的时候,主线程则会返回,继续执行主线程的任务,而await后面的代码则会作为子线程的回调,交给任意一根线程去执行,执行这个回调的可能是主线程也可能是执行完任务的子线程也可能是其他线程。
返回值是void
public async void TestTest()
{
this.AsyncVoid();
Console.WriteLine("主线程走了");
}
public async void AsyncVoid()
{
Console.WriteLine("线程ID是" + Thread.CurrentThread.ManagedThreadId);
await Task.Run(() =>
{
Console.WriteLine("线程ID是" + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(1000);
});
Console.WriteLine("我是回调");
}
返回值是Task
public async void TestTest()
{
await this.AsyncTask();
Console.WriteLine("主线程走了");
}
public async Task AsyncTask()
{
Task task = Task.Factory.StartNew(() =>
{
Console.WriteLine("子线程开始执行任务");
});
await task;
Console.WriteLine("我是回调");
}
返回值是Task< T >
public async void TestTest()
{
int result = await this.AsyncTaskReturn(1);
Console.WriteLine("Task的返回值是"+result);
Console.WriteLine("主线程走了");
}
public async Task<int> AsyncTaskReturn(int m)
{
Task<int> task1 = AddTask(m);
await task1;
Task<int> task2 = AddTask(task1.Result);
Console.WriteLine("task的结果是"+task1.Result);
await task2;
Task<int> task3 = AddTask(task2.Result);
Console.WriteLine("task的结果是" + task2.Result);
await task3;
Task<int> task4 = AddTask(task3.Result);
Console.WriteLine("task的结果是" + task3.Result);
return task4.Result;
}
public Task<int> AddTask(int m)
{
return Task.Run(() =>
{
return ++m;
});
}
需要注意的是,async本身并不会启动线程,它只是标识了这是一个异步的操作,async只能标识返回值是Task或者是void类型的函数,一个函数可以只有async,但是await只能出现在async标识的函数中,而且await只能等待Task,await后面的代码会被作为一个回调,当子线程执行完任务的时候,则执行回调。一个async中可以有多个await。
wait()函数和awiat的区别:wait()函数会让主线程进入等待状态,一直得到子线程将任务和回调执行完毕,才继续执行主线程的任务,但是当主线程遇到await的时候则会返回,继续执行主线程的任务。
GetAwaiter()等待
public async void TestTest()
{
this.StrTask();
Console.WriteLine("主线程走了");
}
public async void StrTask()
{
Task<string> task= Task.Run(() =>
{
Thread.Sleep(500);
return "12346";
});
var taskAwaiter = task.GetAwaiter();
if (!taskAwaiter.IsCompleted)
{
Console.WriteLine("子线程任务未完成");
}
await task;
if (taskAwaiter.IsCompleted)
{
Console.WriteLine("子线程得到的结果是"+taskAwaiter.GetResult());
}
taskAwaiter.OnCompleted(() =>
{
Console.WriteLine("子线程终于执行完毕了");
});
}
通过Task的GetAwaiter()的函数得到TaskAwaiter对象
TaskAwaiter常用属性和函数
IsCompleted 得到一个bool值判断任务是否执行完毕
OnCompleted() 传入一个Action作为回调
GetResult() 得到子线程的返回值