.NET中如何在同步代码块中调用异步方法

更新记录
本文迁移自Panda666原博客,原发布时间:2021年7月2日。

在同步代码块中调用异步方法,方法有很多。

一、对于有返回值的Task#

在同步代码块中直接访问 Task 的 Result 属性,这会阻塞调用线程直到返回Result为止。

代码实例:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace PandaTestClass
{
    class Program
    {
        private static async Task<(string, string)> DoSomething()
        {
            //用于返回值
            (string, string) result = ("?", "?");

            //任务1
            await Task.Run(() => {
                //模拟耗时任务
                for (int i = 0; i <= 100; i += 20)
                {
                    Console.WriteLine($"任务1,当前执行到:{i}%");
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }
                //写入返回值
                result.Item1 = "任务1完成";
            });

            //任务2
            await Task.Run(() => {
                //模拟耗时任务
                for (int i = 0; i <= 100; i += 20)
                {
                    Console.WriteLine($"任务2,当前执行到:{i}%");
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }
                //写入返回值
                result.Item2 = "任务2完成";
            });

            //确保任务执行完成
            Task.WaitAll(new Task[] { });
            //返回返回值
            return result;
        }

        static void Main(string[] args)
        {
            //同步块中使用异步方法
            //这里会阻塞主线程
            (string t1, string t2) result = DoSomething().Result;
            //执行完成
            Console.WriteLine("DoSomething Success");
            //获得结果集1
            Console.WriteLine(result.t1);
            //获得结果集2
            Console.WriteLine(result.t2);

            //wait
            Console.WriteLine("Main Suceess");
            Console.ReadKey();
        }
    }
}

二、使用Task.Run()方法包裹#

强烈推荐该方法。

代码实例:

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace PandaTestClass
{
    class Program
    {
        /// <summary>
        /// 异步方法
        /// </summary>
        /// <returns></returns>
        private static async Task<(string, string)> DoSomething()
        {
            //用于返回值
            (string, string) result = ("?", "?");

            //任务1
            await Task.Run(() => {
                //模拟耗时任务
                for (int i = 0; i <= 100; i += 20)
                {
                    Console.WriteLine($"任务1,当前执行到:{i}%");
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }

                //写入返回值
                result.Item1 = "任务1完成";
            });

            //任务2
            await Task.Run(() => {
                //模拟耗时任务
                for (int i = 0; i <= 100; i += 20)
                {
                    Console.WriteLine($"任务2,当前执行到:{i}%");
                    Thread.Sleep(TimeSpan.FromSeconds(1));
                }

                //写入返回值
                result.Item2 = "任务2完成";
            });

            //确保任务执行完成
            Task.WaitAll(new Task[] { });
            //返回返回值
            return result;
        }

        static void Main(string[] args)
        {
            //同步块中使用异步方法
            //这里会阻塞主线程
            Task<(string t1, string t2)> returnValue = Task.Run(async () => {
                (string t1, string t2) r = await DoSomething();
                return r;
            });

            //执行完成
            //获得结果集1
            Console.WriteLine(returnValue.Result.t1);
            //获得结果集2
            Console.WriteLine(returnValue.Result.t2);

            //wait
            Console.WriteLine("Main Suceess");
            Console.ReadKey();
        }
    }
}

作者:重庆熊猫

出处:https://www.cnblogs.com/cqpanda/p/16153533.html

版权:本作品采用「不论是否商业使用都不允许转载,否则按3元1字进行收取费用」许可协议进行许可。

posted @   重庆熊猫  阅读(597)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示