标签:中文 oid imp bsp bgp back readline 异步调用 block
class Program
{
static int index = 1;
static void Log(string str)
{
Console.WriteLine((index++) + ". " + str + ". ThreadId:" + Thread.CurrentThread.ManagedThreadId);
}
static void Main(string[] args)
{
//解决.net core控制台输出中文乱码的代码
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
//async 不能用于Main方法,所以在这里单独使用一个方法来调用,各位可以试试,编译不过,但VS就是不会告诉你错误在哪里
ExcuteAsync();
Console.ReadLine();
}
static async void ExcuteAsync() {
Log("异步方法调用前");
var ret = AsyncMethod();
Log("异步方法调用后");
Log(await ret);
Log("异步方法使用await后");
}
static async Task<string> AsyncMethod() {
Log("异步方法开始");
var task = Task.Run<string>(() =>
{
Log("异步方法内部开始");
Thread.Sleep(3000);
Log("异步方法内部结束");
return "来自异步方法内部的结果";
});
Log("异步方法结束");
var ret = await task;
Log("异步方法await结束");
return ret;
}
}
控制台输出结果
1. 异步方法调用前. ThreadId:1
2. 异步方法开始. ThreadId:1
3. 异步方法结束. ThreadId:1
4. 异步方法内部开始. ThreadId:3
5. 异步方法调用后. ThreadId:1
6. 异步方法内部结束. ThreadId:3
7. 异步方法await结束. ThreadId:3
8. 来自异步方法内部的结果. ThreadId:3
9. 异步方法使用await后. ThreadId:3
为了描述更方便,为每条输出都添加了序号。 为了更清晰的知道每一步的执行顺序以及所在的线程,均添加了ThreadId
我们把ExcuteAsync方法里的await ret,改成ret.Result看看效果
1. 异步方法调用前. ThreadId:1
2. 异步方法开始. ThreadId:1
3. 异步方法结束. ThreadId:1
4. 异步方法内部开始. ThreadId:3
5. 异步方法调用后. ThreadId:1
6. 异步方法内部结束. ThreadId:3
7. 异步方法await结束. ThreadId:3
8. 来自异步方法内部的结果. ThreadId:1
9. 异步方法使用await后. ThreadId:1
第8-9条输出线程变了,可见是主线程被挂起了,等待子线程结束后继续往下执行。那么如果在AsyncMethod里也使用Result,效果又是什么样的?
我们把AsyncMethod方法里的await task改成task.Result,看输出结果
1. 异步方法调用前. ThreadId:1
2. 异步方法开始. ThreadId:1
3. 异步方法结束. ThreadId:1
4. 异步方法内部开始. ThreadId:3
5. 异步方法内部结束. ThreadId:3
6. 异步方法await结束. ThreadId:1
7. 异步方法调用后. ThreadId:1
8. 来自异步方法内部的结果. ThreadId:1
9. 异步方法使用await后. ThreadId:1
现在只有Task内部的输出是在子线程了。可见,使用Result的话会失去异步的效果,换句话说,使用Result就不再是异步调用了。
附:文笔不好,只能用习惯的代码来描述,希望能给读者带来帮助。
标签:中文 oid imp bsp bgp back readline 异步调用 block
原文地址:http://www.cnblogs.com/rainhat/p/6847459.html