webapi,Action提供的接收参数的方式:【Fromxxxx】

1.通过ActionArgument
2.通过QueryParams,直接写参数,默认FromQuery特性
3.通过QueryParams,使用对象,同时声明FromQuery特性

https://www.iaspnetcore.com/blog/blogpost/594960eb84cd453380655bc9/aspnet-core-mvc-model-binding-fromheader-fromquery-fromroute-fromform-usage-scenarios-and-principles

很多人搞不清FromQuery和FromRoute的区别。本文举例解释一下。

FromRoute
FromQuery
FromForm
FromBody
FromHeader
FromServices

[FromXXX] 是告诉后台的控制器在获取前台页面传递过来的参数是放在请求内容的哪个地方的,从而确定从哪里获取参数信息。

从前端发过来的请求,由三个部分组成

Request.url

Request.Header

Reques.Body

参数可能放在这三个地方之一。[FromXXX]即对应了这三处地方。

task.run多线程的坑

####问题
1.task.run默认会有线程池启用,但因为受ThreadPoolTaskScheduler的默认配置,启用多个子线程时,会1秒开启一个,如果想要减少整体运行时间并发多个线程,这其实达不到想要的效果

解决方案:

1.如果子方法有提供aync的方法,使用它

obj.getMethonAysnc();

2.指定CreateOptions为LongRunning(这样便会直接开一个新线程,而不是使用线程池)

//使用Task.Factory.StartNew比较方便的地方是方便设置TaskCreationOptions参数;
 Task.Factory.StartNew(()=> {
                Console.WriteLine("");
                Thread.Sleep(100);
            },TaskCreationOptions.LongRunning);
//new Task的使用方式,可以看到需要new一个task新类
  var task = new Task(() => { 
                Console.WriteLine("");
                Thread.Sleep(100);
            }, TaskCreationOptions.LongRunning);
 task.Start();

3.显示指定线程池的最小值和最大值

            ThreadPool.SetMinThreads(90, 100);
            ThreadPool.SetMaxThreads(90, 100);

            for (int i = 0; i < 20; i++)
            {
                // Task.Factory.StartNew();
                Task.Run(() =>
                {
                    Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.sss"));
                    Thread.Sleep(5000);
                });
            }

4.如果确实是各子线程无相关性,使用Parallel并发类

 //最简单的使用,Parallel.Invoke(...);
  public void Run1()
        {
            Thread.Sleep(2000);
            Console.WriteLine("Task 1 is cost 2 sec");
        }
        public void Run2()
        {
            Thread.Sleep(3000);
            Console.WriteLine("Task 2 is cost 3 sec");
        }

        private Stopwatch stopWatch = new Stopwatch();
        public void ParallelInvokeMethod()
        {
            stopWatch.Start();
            Parallel.Invoke(Run1, Run2);
            stopWatch.Stop();
            Console.WriteLine("Parallel run " + stopWatch.ElapsedMilliseconds + " ms.");

            stopWatch.Restart();
            Run1();
            Run2();
            stopWatch.Stop();
            Console.WriteLine("Normal run " + stopWatch.ElapsedMilliseconds + " ms.");
        }

参考:
https://www.cnblogs.com/springsnow/p/9409205.html
https://www.cnblogs.com/walterlv/p/10236390.html
https://www.cnblogs.com/yunfeifei/p/3993401.html

了解 .NET 的默认 TaskScheduler 和线程池(ThreadPool)设置,避免让 Task.Run 的性能急剧降低

如果去掉线程池,默认会一秒生成一个新线程。
参考:https://www.cnblogs.com/soundcode/p/12160259.html
参考:https://www.cnblogs.com/atomy/p/11984179.html
重点参考:https://www.cnblogs.com/walterlv/p/10236390.html

            //ThreadPool.SetMinThreads(90, 100);
            //ThreadPool.SetMaxThreads(90, 100);
            Task.Run(() =>
            {
                while (true)
                {
                    int work = 0, com = 0;
                    ThreadPool.GetAvailableThreads(out work, out com);
                    Console.WriteLine($"{work}:{com}");
                    Thread.Sleep(100);
                }
            });


            for (int i = 0; i < 20; i++)
            {
                Task.Run(() =>
                {
                    Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.sss"));
                    Thread.Sleep(5000);
                });
            }

            Console.Read();

            return;