本文介绍: 1、控制台测试await/async2、C# 5.0 .Net framework4.5 CLR4.0 以后才有,本身是一种语法糖从打印出来的两种执行顺序来看,加了await以后,主线程运行到await这行就会执行回主线程任务。而await后面的代码将由主线程或其他线程来执行await后面的代码,会被封装成委托,在await task之后成为回调(编译器功能,状态机实现) ,这个回调的线程是不确定的,可能是主线程,可能是子线程也可能是其他线程。它可以等价于这里包起来。
一、介绍
1、控制台测试await/async
2、C# 5.0 .Net framework4.5 CLR4.0 以后才有,本身是一种语法糖
二、基本测试
1、不加await测试。
private async static Task TestAsync()
{
Log.Info($"当前主线程id={Thread.CurrentThread.ManagedThreadId}");
NoReturnNoAwait();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(300);
Log.Info($"Main Thread Task ManagedThreadID = {Thread.CurrentThread.ManagedThreadId}");
}
}
private static async void NoReturnNoAwait()
{
Log.Info($"NoReturn Sleep before await,ThreadID={Thread.CurrentThread.ManagedThreadId}");
TaskFactory taskFactory = new TaskFactory();
Task task = taskFactory.StartNew(() =>
{
Log.Info($"NoReturn Sleep before,ThreadID={Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(3000);
Log.Info($"NoReturn Sleep after,ThreadID={Thread.CurrentThread.ManagedThreadId}");
});
Log.Info($"NoReturn Sleep after await,ThreadID={Thread.CurrentThread.ManagedThreadId}");
}
2、加await测试。
private async static Task TestAsync()
{
Log.Info($"当前主线程id={Thread.CurrentThread.ManagedThreadId}");
NoReturn();
//NoReturnNoAwait();
for (int i = 0; i < 10; i++)
{
Thread.Sleep(300);
Log.Info($"Main Thread Task ManagedThreadID = {Thread.CurrentThread.ManagedThreadId}");
}
}
private static async void NoReturn()
{
Log.Info($"NoReturn Sleep before await,ThreadID={Thread.CurrentThread.ManagedThreadId}");
TaskFactory taskFactory = new TaskFactory();
Task task = taskFactory.StartNew(() =>
{
Log.Info($"NoReturn Sleep before,ThreadID={Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(3000);
Log.Info($"NoReturn Sleep after,ThreadID={Thread.CurrentThread.ManagedThreadId}");
});
await task; //主线程到这里就返回了,执行主线程任务
Log.Info($"NoReturn Sleep after await,ThreadID={Thread.CurrentThread.ManagedThreadId}");
}
结果:从打印出来的两种执行顺序来看,加了await以后,主线程运行到await这行就会执行
回主线程任务。而await后面的代码将由主线程或其他线程来执行原理:await后面的代码,会被封装成委托,在await task之后成为回调(编译器功能,状态机实现) ,这个回调的线程是不确定的,可能是主线程,可能是子线程也可能是其他线程。
它可以等价于task.ContinueWith(t=>{}) 这里包起来
验证一下:
private async void AwaitTest() { //方法一: NoReturn(); //方法二: TaskFactory taskFactory = new TaskFactory(); Task task = taskFactory.StartNew(() => { Log.Info($"NoReturn Sleep before,ThreadID={Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(3000); Log.Info($"NoReturn Sleep after,ThreadID={Thread.CurrentThread.ManagedThreadId}"); }); task.ContinueWith(t => { callBack(); }); await task; } private static async void NoReturnNoAwait() { Log.Info($"NoReturn Sleep before await,ThreadID={Thread.CurrentThread.ManagedThreadId}"); TaskFactory taskFactory = new TaskFactory(); Task task = taskFactory.StartNew(() => { Log.Info($"NoReturn Sleep before,ThreadID={Thread.CurrentThread.ManagedThreadId}"); Thread.Sleep(3000); Log.Info($"NoReturn Sleep after,ThreadID={Thread.CurrentThread.ManagedThreadId}"); }); Log.Info($"NoReturn Sleep after await,ThreadID={Thread.CurrentThread.ManagedThreadId}"); } private void callBack() { Log.Info($"我是一个回调。。"); Log.Info($"NoReturn Sleep after await,ThreadID={Thread.CurrentThread.ManagedThreadId}"); }
三、返回值问题
1、不需要传值的时候,我们返回值就写成Task或者void都可以
2、需要传值的话 ,可以使用这种带泛型传值
四、小案例
private void MainThread()
{
Log.Info("主线程Start");
Async();
Log.Info($"aaa {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
}
private async void Async()
{
Log.Info($"ddd {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
await Task.Run(() =>
{
Thread.Sleep(500);
Log.Info($"bbb {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
});
Log.Info($"ccc {Thread.CurrentThread.ManagedThreadId.ToString("00")}");
}
猜测执行顺序:
1、打印主线程Start
2、主线程进入Async方法,打印ddd
3、碰到了await,主线程返回回去执行,打印aaa
4、子线程等待500毫秒后,并行打印bbb
5、最后回调打印ccc
公布结果:
原文地址:https://blog.csdn.net/weixin_46711336/article/details/135409793
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_52458.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。