异步编程学习总结1

示例:

static static void Main(string[] args)
        {
            //同步方法
            {
                string filename = @"C:\TEMP\1.txt";
                File.WriteAllText(filename, "hello world");
                string strContext = File.ReadAllText(filename);
                Console.WriteLine(strContext);
            }

        }
static async Task Main(string[] args)
        {

            //异步方法
            {
                string filename = @"C:\TEMP\1.txt";
                await File.WriteAllTextAsync(filename, "hello world");
                string strContext = await File.ReadAllTextAsync(filename);
                Console.WriteLine(strContext);
            }
        }

 

上面两段代码执行结果是一样的,都是往txt文本中写入一段文字并读取出来。

async,await基本使用总结:
1.异步方法的返回值一般是Task<T>,T是真正的返回值类型,Task<int>。异步方法名字以Async结尾。
2.即使没有返回值,也最好把返回值声明为非泛型的Task。
3.调用异步方法时,一般在方法前面加上await,这样拿到的返回值就是泛型指定的T类型。
4.异步方法的“传染性”,一个方法中如果有await调用,则这个方法也必须修饰为async。
5.如果一个方法既有同步方法,又有异步方法,尽量调用异步方法。
6.async,await不等于“多线程” 。 

调用await之前和之后可能不是一个线程在执行程序,下面做一个测试,在await语句执行前后分别打印出线程的ID。

        /// <summary>
        /// 线程ID测试
        /// </summary>
        /// <returns></returns>
        public static async Task ThreadTest()
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 10000; i++)
            {
                sb.Append("XXXXXXXXXXXXXXXXXXXXX");
            }
            await File.WriteAllTextAsync(@"C:\TEMP\2.txt", sb.ToString());
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
        }

方法调用: 

 static async Task Main(string[] args)
        {
           await ThreadTest();
        }

执行结果:

await调用的等待期间,.net会把当前的线程返回给线程池,等异步方法调用执行完毕后,框架会从线程池再取出来一个线程执行后面的代码。

如果在await语句执行时间很短,可能前后还是同一个线程ID。

异步方法的代码并不会自动在新线程中执行,除非把代码放到新线程中执行。

        /// <summary>
        /// 自定义的异步方法
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static async Task<double> CalcAsync(int n)
        {
            Console.WriteLine("方法中的线程ID:" + Thread.CurrentThread.ManagedThreadId);
            double result = 0;
            Random rand = new Random();
            for (int i = 0; i < n * n; i++)
            {
                result += rand.NextDouble();
            }
            return result;
        }

调用:

static async Task Main(string[] args)
        {
            Console.WriteLine("调用之前的线程ID:" + Thread.CurrentThread.ManagedThreadId);
            double rel = await CalcAsync(5000);
            Console.WriteLine($"rel={rel}");
            Console.WriteLine("调用之后的线程ID:" + Thread.CurrentThread.ManagedThreadId);
        }

执行结果:

 

自定义一个异步方法名称为CalcAsync,然后在main方法中调用该异步方法,在异步方法调用前后都打印出线程ID,最后发现为同一线程在处理程序。这样说明了不是调用异步方法就会使用新的线程。

如果要想使方法在新的线程中执行,需要把要执行的代码以委托的形式传递给Task.Run(),这样就会从线程池中取出一个线程执行我们的委托,格式如下:

await Task.Run(()=>{

    //耗时操作代码,可以return返回值

})

        /// <summary>
        /// 自定义的异步方法
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static async Task<double> CalcAsync(int n)
        {
            return await Task.Run(() =>
             {
                 Console.WriteLine("方法中的线程ID:" + Thread.CurrentThread.ManagedThreadId);
                 double result = 0;
                 Random rand = new Random();
                 for (int i = 0; i < n * n; i++)
                 {
                     result += rand.NextDouble();
                 }
                 return result;
             });
        }

调用:

static async Task Main(string[] args)
        {
            Console.WriteLine("调用之前的线程ID:" + Thread.CurrentThread.ManagedThreadId);
            double rel = await CalcAsync(5000);
            Console.WriteLine($"rel={rel}");
            Console.WriteLine("调用之后的线程ID:" + Thread.CurrentThread.ManagedThreadId);
        }

执行结果:

 调用异步方法前的线程ID为1,执行异步操作的线程ID为4。执行异步操作时使用的是新的线程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
同步API和异步API是编程中常见的概念。 同步API是指调用一个函数后,必须等待函数执行完毕并返回结果后才能继续执行后续的代码。同步API可以通过return语句返回结果,可以直接获取到函数执行的返回值。 异步API是指调用一个函数后,不需要等待函数执行完毕,而是继续执行后续的代码。异步API不会通过return语句返回结果,而是通过回调函数传递执行结果。异步API会将任务放到异步队列中,等待主线程空闲时再执行。 区别一:同步API可以通过return语句返回结果,而异步API不能通过return语句返回结果。 区别二:同步API会阻塞后续代码的执行,而异步API不会阻塞后续代码的执行。 回调函数是一种处理异步任务结果的方式。当异步任务执行完毕后,会调用回调函数,并将执行结果作为参数传递给回调函数。回调函数可以通过参数获取异步任务的执行结果。 总结起来,同步API是会阻塞后续代码执行的,可以直接获取函数的返回值;而异步API是不会阻塞后续代码执行的,需要通过回调函数来获取执行结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Node.js学习记录七:Node的异步API和同步API](https://blog.csdn.net/m0_48459838/article/details/113844964)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [普歌-Node.js异步编程(区别与分析)](https://blog.csdn.net/BZJ0528_/article/details/109921929)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值