• 老人言:尽量用异步


      官方和老人言,asp.net core中尽量用异步,为什么呢?接下来是个小demo,看看同步异步的差别吧,或许通过这个demo,就明白官方和老人的良苦用心了。

    1、创建一个sql server的表

    CREATE TABLE [dbo].[Students](
      [StuNo] [varchar](50) NOT NULL,
      [Name] [varchar](50) NULL,
      [CardID] [varchar](18) NULL,
      [Sex] [varchar](4) NULL,
      [Birthday] [datetime] NULL,
      [ClassID] [int] NULL,
     CONSTRAINT [PK_dbo.Students] PRIMARY KEY CLUSTERED 
    (
      [StuNo] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO

    2、创建一个asp.net core api项目,5.0的

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Data.SqlClient;
    using Microsoft.Extensions.Logging;
    using System;
    using System.Threading.Tasks;
    
    namespace AsyncWebAPI.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class StudentController : ControllerBase
        {
            private readonly ILogger<StudentController> _logger;
    
            public StudentController(ILogger<StudentController> logger)
            {
                _logger = logger;
            }
            [HttpDelete("/deleteall")]
            public bool DeleteAll()
            {
                _logger.LogInformation("删除全部");
                using var con = new SqlConnection("server=.;database=TestManageDB;uid=sa;pwd=sa;");
                var sql = @"delete from  [dbo].[Students]";
                var cmd = new SqlCommand(sql, con);
                con.Open();
                var result = cmd.ExecuteNonQuery();
                con.Close();
                return true;
            }
    
            [HttpPost("/addstudent")]
            public Student AddEntity([FromBody] Student student)
            {
                _logger.LogInformation("同步添加");
                return SavaEntity(student);
            }
            Student SavaEntity(Student student)
            {
                student.StuNo = Guid.NewGuid().ToString();
                using var con = new SqlConnection("server=.;database=TestManageDB;uid=sa;pwd=sa;");
                var sql = @"INSERT INTO [dbo].[Students]
               ([StuNo]
               ,[Name]
               ,[CardID]
               ,[Sex]
               ,[Birthday]
               ,[ClassID]
               )
         VALUES
               (@StuNo
               ,@Name
               ,@CardID
               ,@Sex
               ,@Birthday
               ,@ClassID
               )";
                var cmd = new SqlCommand(sql, con);
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@StuNo", Value = student.StuNo, SqlDbType = System.Data.SqlDbType.VarChar });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@Name", Value = student.Name, SqlDbType = System.Data.SqlDbType.VarChar });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@CardID", Value = student.CardID, SqlDbType = System.Data.SqlDbType.VarChar });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@Sex", Value = student.Sex, SqlDbType = System.Data.SqlDbType.VarChar });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@Birthday", Value = student.Birthday, SqlDbType = System.Data.SqlDbType.DateTime });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@ClassID", Value = student.ClassID, SqlDbType = System.Data.SqlDbType.Int });
                con.Open();
                var result = cmd.ExecuteNonQuery();
                con.Close();
                return student;
            }
    
            [HttpPost("/addstudentasync")]
            public async Task<Student> AddEntityAsync([FromBody] Student student)
            {
                _logger.LogInformation("异步添加");
                return await SavaEntityAsync(student);
            }
    
            async Task<Student> SavaEntityAsync(Student student)
            {
                student.StuNo = Guid.NewGuid().ToString();
                using var con = new SqlConnection("server=.;database=TestManageDB;uid=sa;pwd=sa;");
                var sql = @"INSERT INTO [dbo].[Students]
               ([StuNo]
               ,[Name]
               ,[CardID]
               ,[Sex]
               ,[Birthday]
               ,[ClassID]
               )
         VALUES
               (@StuNo
               ,@Name
               ,@CardID
               ,@Sex
               ,@Birthday
               ,@ClassID
               )";
                var cmd = new SqlCommand(sql, con);
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@StuNo", Value = student.StuNo, SqlDbType = System.Data.SqlDbType.VarChar });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@Name", Value = student.Name, SqlDbType = System.Data.SqlDbType.VarChar });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@CardID", Value = student.CardID, SqlDbType = System.Data.SqlDbType.VarChar });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@Sex", Value = student.Sex, SqlDbType = System.Data.SqlDbType.VarChar });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@Birthday", Value = student.Birthday, SqlDbType = System.Data.SqlDbType.DateTime });
                cmd.Parameters.Add(new SqlParameter { ParameterName = "@ClassID", Value = student.ClassID, SqlDbType = System.Data.SqlDbType.Int });
                await con.OpenAsync();
                var result = await cmd.ExecuteNonQueryAsync();
                await con.CloseAsync();
                return student;
            }
        }
    
        public class Student
        {
            public string StuNo { get; set; }
            public string Name { get; set; }
            public string CardID { get; set; }
            public string Sex { get; set; }
            public DateTime Birthday { get; set; }
            public int ClassID { get; set; }
    
        }
    }

    3、创建一个控制台程序,了是.net core 5.0的

    using Newtonsoft.Json;
    using System;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace AsyncRquestClient
    {
        class ProgramAsync
        {
            static int times = 100;
            static async Task Main(string[] args)
            {
                while (true)
                {
                    Console.WriteLine("输入循环次数");
                    times = int.Parse(Console.ReadLine());
    
                    #region 同步
    
                    Console.WriteLine("-----------------同步调同步API------------------");
                    SyncCallSyncAPI();
                    Console.ReadLine();
    
                    Console.WriteLine("-----------------同步调异步API------------------");
                    SyncCallAsyncAPI();
                    Console.ReadLine();
    
                    Console.WriteLine("-----------------TaskFactory同步调同步API------------------");
                    TaskFactorySyncCallSyncAPI();
                    Console.ReadLine();
    
                    Console.WriteLine("-----------------TaskFactory同步调异步API------------------");
                    TaskFactorySyncCallAsyncAPI();
                    Console.ReadLine();
                    #endregion
                 
                    #region 异步
                    Console.WriteLine("-----------------异步调异步API------------------");
                    await AsyncCallAsyncAPI();
                    Console.ReadLine();
    
                    Console.WriteLine("-----------------异步调同步API------------------");
                    await AsyncCallSyncAPI();
                    Console.ReadLine();
                
                    Console.WriteLine("-----------------TaskFactory异步调异步API------------------");
                    await TaskFactoryAsyncCallAsyncAPI();
                    Console.ReadLine();
    
                    Console.WriteLine("-----------------TaskFactory异步调同步API------------------");
                    await TaskFactoryAsyncCallSyncAPI();
                    Console.ReadLine();
                    #endregion
                }
            }
            #region 异常
            /// <summary>
            /// 异步调异步API
            /// </summary>
            /// <returns></returns>
            async static Task AsyncCallAsyncAPI()
            {
                var r = DeleteAllAsync().Result;
                Console.WriteLine($"异步调异步API开始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}");
                for (int i = 1; i <= times; i++)
                {
                    try
                    {
                        var student = new Student { Name = "张三" + i, Birthday = DateTime.Now, CardID = "C0000" + i, ClassID = 1, Sex = "" };
                        using var client = new HttpClient();
                        client.BaseAddress = new Uri("https://localhost:5001");
                        var request = new HttpRequestMessage(HttpMethod.Post, "addstudentasync");
                        request.Content = new StringContent(JsonConvert.SerializeObject(student), Encoding.UTF8, "application/json");
                        var response = await client.SendAsync(request);
                        if (response.IsSuccessStatusCode)
                        {
                            var content = await response.Content.ReadAsStringAsync();
                            var stu = JsonConvert.DeserializeObject<Student>(content);
    
                        }
                        else
                        {
                            var content = response.Content.ReadAsStringAsync().Result;
                            Console.WriteLine("同步调同步添加错误返回值:" + content);
    
                        }
                    }
                    catch (Exception exc)
                    {
                        Console.WriteLine(exc.Message);
                    }
                }
    
            }
            /// <summary>
            /// TaskFactory异步调异步API
            /// </summary>
            /// <returns></returns>
            static async Task TaskFactoryAsyncCallAsyncAPI()
            {
                var r = await DeleteAllAsync();
                Console.WriteLine($"TaskFactory异步调异步开API始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}");
                for (int i = 1; i <= times; i++)
                {
                    await Task.Factory.StartNew(async () =>
                    {
                        try
                        {
                            var student = new Student { Name = "张三" + i, Birthday = DateTime.Now, CardID = "C0000" + i, ClassID = 1, Sex = "" };
                            using var client = new HttpClient();
                            client.BaseAddress = new Uri("https://localhost:5001");
                            var request = new HttpRequestMessage(HttpMethod.Post, "addstudentasync");
                            request.Content = new StringContent(JsonConvert.SerializeObject(student), Encoding.UTF8, "application/json");
                            var response = await client.SendAsync(request);
                            if (response.IsSuccessStatusCode)
                            {
                                var content = await response.Content.ReadAsStringAsync();
                                var stu = JsonConvert.DeserializeObject<Student>(content);
    
                            }
                            else
                            {
                                var content = await response.Content.ReadAsStringAsync();
                                Console.WriteLine("异步调异步添加错误返回值:" + content);
    
                            }
                        }
                        catch (Exception exc)
                        {
                            Console.WriteLine(exc.Message);
                        }
                    });
                }
    
            }
    
            /// <summary>
            /// 异步调同步API
            /// </summary>
            /// <returns></returns>
            async static Task AsyncCallSyncAPI()
            {
                var r = DeleteAllAsync().Result;
                Console.WriteLine($"异步调同步API开始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}");
                for (int i = 1; i <= times; i++)
                {
                    try
                    {
                        var student = new Student { Name = "张三" + i, Birthday = DateTime.Now, CardID = "C0000" + i, ClassID = 1, Sex = "" };
                        using var client = new HttpClient();
                        client.BaseAddress = new Uri("https://localhost:5001");
                        var request = new HttpRequestMessage(HttpMethod.Post, "addstudent");
                        request.Content = new StringContent(JsonConvert.SerializeObject(student), Encoding.UTF8, "application/json");
                        var response = await client.SendAsync(request);
                        if (response.IsSuccessStatusCode)
                        {
                            var content = await response.Content.ReadAsStringAsync();
                            var stu = JsonConvert.DeserializeObject<Student>(content);
    
                        }
                        else
                        {
                            var content = response.Content.ReadAsStringAsync().Result;
                            Console.WriteLine("同步调同步添加错误返回值:" + content);
    
                        }
                    }
                    catch (Exception exc)
                    {
                        Console.WriteLine(exc.Message);
                    }
                }
    
            }
            /// <summary>
            /// TaskFactory异步调同步API
            /// </summary>
            /// <returns></returns>
            static async Task TaskFactoryAsyncCallSyncAPI()
            {
                var r = await DeleteAllAsync();
                Console.WriteLine($"TaskFactory异步调同步API开始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}");
                for (int i = 1; i <= times; i++)
                {
                    await Task.Factory.StartNew(async () =>
                    {
                        try
                        {
                            var student = new Student { Name = "张三" + i, Birthday = DateTime.Now, CardID = "C0000" + i, ClassID = 1, Sex = "" };
                            using var client = new HttpClient();
                            client.BaseAddress = new Uri("https://localhost:5001");
                            var request = new HttpRequestMessage(HttpMethod.Post, "addstudent");
                            request.Content = new StringContent(JsonConvert.SerializeObject(student), Encoding.UTF8, "application/json");
                            var response = await client.SendAsync(request);
                            if (response.IsSuccessStatusCode)
                            {
                                var content = await response.Content.ReadAsStringAsync();
                                var stu = JsonConvert.DeserializeObject<Student>(content);
    
                            }
                            else
                            {
                                var content = await response.Content.ReadAsStringAsync();
                                Console.WriteLine("异步调异步添加错误返回值:" + content);
    
                            }
                        }
                        catch (Exception exc)
                        {
                            Console.WriteLine(exc.Message);
                        }
                    });
                }
    
            }
            #endregion
    
            #region 同步
            /// <summary>
            /// 同步调同步API
            /// </summary>
            static void SyncCallSyncAPI()
            {
                var r = DeleteAllAsync().Result;
                Console.WriteLine($"同步调同步开始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}");
                for (int i = 1; i <= times; i++)
                {
                    try
                    {
                        var student = new Student { Name = "张三" + i, Birthday = DateTime.Now, CardID = "C0000" + i, ClassID = 1, Sex = "" };
                        using var client = new HttpClient();
                        client.BaseAddress = new Uri("https://localhost:5001");
                        var request = new HttpRequestMessage(HttpMethod.Post, "addstudent");
                        request.Content = new StringContent(JsonConvert.SerializeObject(student), Encoding.UTF8, "application/json");
                        var response = client.SendAsync(request).Result;
                        if (response.IsSuccessStatusCode)
                        {
                            var content = response.Content.ReadAsStringAsync().Result;
                            var stu = JsonConvert.DeserializeObject<Student>(content);
    
                        }
                        else
                        {
                            var content = response.Content.ReadAsStringAsync().Result;
                            Console.WriteLine("同步调同步添加错误返回值:" + content);
    
                        }
                    }
                    catch (Exception exc)
                    {
                        Console.WriteLine(exc.Message);
                    }
                }
            }
            static void TaskFactorySyncCallSyncAPI()
            {
                var r = DeleteAllAsync().Result;
                Console.WriteLine($"TaskFactory异步调同步API开始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}");
                for (int i = 1; i <= times; i++)
                {
                    var result = Task.Factory.StartNew(async () =>
                      {
                          try
                          {
                              var student = new Student { Name = "张三" + i, Birthday = DateTime.Now, CardID = "C0000" + i, ClassID = 1, Sex = "" };
                              using var client = new HttpClient();
                              client.BaseAddress = new Uri("https://localhost:5001");
                              var request = new HttpRequestMessage(HttpMethod.Post, "addstudent");
                              request.Content = new StringContent(JsonConvert.SerializeObject(student), Encoding.UTF8, "application/json");
                              var response = await client.SendAsync(request);
                              if (response.IsSuccessStatusCode)
                              {
                                  var content = await response.Content.ReadAsStringAsync();
                                  var stu = JsonConvert.DeserializeObject<Student>(content);
    
                              }
                              else
                              {
                                  var content = await response.Content.ReadAsStringAsync();
                                  Console.WriteLine("异步调异步添加错误返回值:" + content);
    
                              }
                          }
                          catch (Exception exc)
                          {
                              Console.WriteLine(exc.Message);
                          }
                      }).Result;
                }
    
            }
            /// <summary>
            /// 同步调异步API
            /// </summary>
            static void SyncCallAsyncAPI()
            {
                var r = DeleteAllAsync().Result;
                Console.WriteLine($"同步调异步开始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}");
    
                for (int i = 1; i <= times; i++)
                {
                    try
                    {
                        var student = new Student { Name = "张三" + i, Birthday = DateTime.Now, CardID = "C0000" + i, ClassID = 1, Sex = "" };
                        using var client = new HttpClient();
                        client.BaseAddress = new Uri("https://localhost:5001");
                        var request = new HttpRequestMessage(HttpMethod.Post, "addstudentasync");
                        request.Content = new StringContent(JsonConvert.SerializeObject(student), Encoding.UTF8, "application/json");
                        var response = client.SendAsync(request).Result;
                        if (response.IsSuccessStatusCode)
                        {
                            var content = response.Content.ReadAsStringAsync().Result;
                            var stu = JsonConvert.DeserializeObject<Student>(content);
    
                        }
                        else
                        {
                            var content = response.Content.ReadAsStringAsync().Result;
                            Console.WriteLine("同步调异步添加错误返回值:" + content);
    
                        }
                    }
                    catch (Exception exc)
                    {
                        Console.WriteLine(exc.Message);
                    }
                }
            }
    
            static void TaskFactorySyncCallAsyncAPI()
            {
                var r = DeleteAllAsync().Result;
                Console.WriteLine($"TaskFactory异步调同步API开始时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")}");
                for (int i = 1; i <= times; i++)
                {
                    var result = Task.Factory.StartNew(async () =>
                    {
                        try
                        {
                            var student = new Student { Name = "张三" + i, Birthday = DateTime.Now, CardID = "C0000" + i, ClassID = 1, Sex = "" };
                            using var client = new HttpClient();
                            client.BaseAddress = new Uri("https://localhost:5001");
                            var request = new HttpRequestMessage(HttpMethod.Post, "addstudentasync");
                            request.Content = new StringContent(JsonConvert.SerializeObject(student), Encoding.UTF8, "application/json");
                            var response = await client.SendAsync(request);
                            if (response.IsSuccessStatusCode)
                            {
                                var content = await response.Content.ReadAsStringAsync();
                                var stu = JsonConvert.DeserializeObject<Student>(content);
    
                            }
                            else
                            {
                                var content = await response.Content.ReadAsStringAsync();
                                Console.WriteLine("异步调异步添加错误返回值:" + content);
    
                            }
                        }
                        catch (Exception exc)
                        {
                            Console.WriteLine(exc.Message);
                        }
                    }).Result;
                }
    
            }
            #endregion
    
    
    
            static async Task<bool> DeleteAllAsync()
            {
                using var client = new HttpClient();
                client.BaseAddress = new Uri("https://localhost:5001");
                var request = new HttpRequestMessage(HttpMethod.Delete, "deleteall");
                var response = await client.SendAsync(request);
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();
                    var result = JsonConvert.DeserializeObject<bool>(content);
                    return result;
                }
                else
                {
                    var content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine("删除错误返回值:" + content);
                    return false;
                }
            }
        }
    
        public class Student
        {
            public string StuNo { get; set; }
            public string Name { get; set; }
            public string CardID { get; set; }
            public string Sex { get; set; }
            public DateTime Birthday { get; set; }
            public int ClassID { get; set; }
    
        }
    
    
    
    }

    4、在sql查询分析器中用这里的语句采集结果

    --检查记录数是否完整
    select count(*) from students;
    --查询时间隔
    select datediff(
    millisecond,
    (select min(birthday) as mi from students),
    (select max(birthday) as ma from students)
    );

    结果如下:

    1000次请求

    同步调同步API

    同步调异步API

    TaskFactory同步调同步API

    TaskFactory同步调异步API

    异步调异步API

    异步调同步API

    TaskFactory异步调异步API

    TaskFactory异步调同步API

    1次(毫秒)

    3190

    3574

    390

    374

    3393

    3140

    356

    387

    2次(毫秒

    3194

    3324

    386

    454

    3370

    3153

    477

    356

    3次(毫秒

    3350

    3343

    443

    397

    3323

    3196

    417

    406

    4次(毫秒

    3207

    3340

    360

    423

    3206

    3083

    433

    403

    5次(毫秒

    3214

    3347

    426

    490

    3167

    3136

    430

    387

    平均

    3231

    3385.6

    401

    427.6

    3291.8

    3141.6

    422.6

    387.8

    客户端调用,异步优势明显;在所有的调用中,服务端的同步要优于异步。

    想要更快更方便的了解相关知识,可以关注微信公众号 
     

     

  • 相关阅读:
    Linux development tools
    Windows Live Mail: getting fewer ads
    美国签证(B1)经验总结
    谁要windows live messenger(msn8.0)的邀请?
    Use Google Calendar in Office
    C#中的ReaderWriterLock和LockFree Data Structure
    第一次看到“谷歌”出现在google.cn上
    解决SQL安装时提示挂起的方法
    asp 常见错误 不能打开注册表关键字 的处理方法
    Apache Web服务器安全配置全攻略
  • 原文地址:https://www.cnblogs.com/axzxs2001/p/15860693.html
Copyright © 2020-2023  润新知