首页 > 技术文章 > 关于C# 异步

nnqwbc 2019-07-01 11:34 原文

关于C# 异步操作整理

  1. 按照个人的理解, 写一个接口用Task异步操作(态度:接受并且学习,您提出宝贵的经验与理解,我会认真学习):

  在主线程中调用异步方法,如果主线程依赖异步方法的返回值那么你一定会去等待子线程的操作时间,但主线程可以继续处理自己的业务,增加了线程的利用率也增加了时间的利用率。(就像人们常说的忙里偷闲一样)

    1.1如果一个项目 分层为:WebAPI(接口),Service(业务处理),Domain(基础操作),ORM。

WebAPI:处理, 接受请求,返回请求结果

Service :拼接操作+数据处理

Domain :基础业务 (增、删、改等)操作

ORM: dapper,EF,sqlSugar 等数据访问ORM 基本够用(封一下使用类)

    1.2分析:

  Service中 如果需要多次数据库操作时, 异步操作就会节省时间同时去请求数据库, 主线程不堵塞,可以1,2,3的发出请求操作,如果是同步,只能等待第一个出现结果,再去执行下一次操作。然后去等待他们的返回值,再去做一些数据处理加工。最终还是要去等待子的处理结果,假设他们都是相同方法,同步则需要消耗 *3的时间,异步则需要 <3的时间(理想状态,主线程也会节省部分时间) 

  2.以下就是一个小的DOME,并不是以上的结果,而是体现异步方法通道的重要性

  重点:保证异步方法之间调用通道的通畅

class Program
{
		//Main方法
        static void Main(string[] args)
        {
            Console.WriteLine(">>>>>>>>>>>>>>>>主线程启动");
            Task<string> task = GetStringAsync1();
            Console.WriteLine("<<<<<<<<<<<<<<<<主线程结束");
            Console.WriteLine($"GetStringAsync1执行结果:{task.Result}");
        }


	#region 异步方法
        static async Task<string> GetStringAsync1()
        {
            Console.WriteLine(">>>>>>>>GetStringAsync1方法启动");
            string str = await GetStringAsync2();
            Console.WriteLine("<<<<<<<<GetStringAsync1方法结束");
            return str;
        }
        static async Task<string> GetStringAsync2()
        {
            Console.WriteLine(">>>>>>>>GetStringAsync2方法启动");
            string str = await GetStringFromTask();
            Console.WriteLine("<<<<<<<<GetStringAsync2方法结束");
            return str;
        }
        static Task<string> GetStringFromTask()
        {
            Console.WriteLine(">>>>GetStringFromTask方法启动");
            Task<string> task = new Task<string>(() =>
            {
                Console.WriteLine(">>任务线程启动");
                Thread.Sleep(1000);
                Console.WriteLine("<<任务线程结束");
                return "hello world";
            });
            task.Start();
            Console.WriteLine("<<<<GetStringFromTask方法结束");
            return task;
        }
	#endregion
}
  2.1结果:

    2.2分析:

  task.Result获取异步方法返回值 , await用于等待子线程结果,而主线程不会因为子线程开始而停止继续执行。

如果通道中出现 .result,则直接堵塞主线程。 

  3.假设:把代码调整  调用多个异步方法

		//Main方法
        static void Main(string[] args)
        {
            Console.WriteLine(">>>>>>>>>>>>>>>>主线程启动");
            Task<string> task = GetStringAsync1();
            Task<string> task1 = GetStringAsync1();
            Task<string> task2 = GetStringAsync1();
            Console.WriteLine("<<<<<<<<<<<<<<<<主线程结束");
            Console.WriteLine($"GetStringAsync1执行结果:{task.Result}");
        }
     3.1结果:

    3.2分析:
从整体运行时间上,就可以看出来不足3秒,也就2秒多一些,而且也可以看出 第二次调用第三次调用中等待1秒的操作,基本是同时执行完毕。

  4.总结一下,在偷时间,充分利用主线程等待与多个子线程之间互不干涉的同时执行的形式。

 

  注:本人也是查看许多大神的文章所理解整理的内容,如果有侵权请联系我(1054529695@qq.com),也欢迎大家查看。

推荐阅读