当前位置:   article > 正文

C# 异步(Task)与线程(Thread/ThreadPool)async Task await_task.factory和thread

task.factory和thread

Task 官网(Docs Microsoft) 
Task 类(NET 7)  
Task.Factory 属性  
异步编程  
ThreadPool 类

在C#中,使用Task可以很方便地执行并行任务。Task是一个表示异步操作的类,它提供了一种简单、轻量级的方式来创建多线程应用程序。

Task执行并行任务的原理
使用Task执行并行任务的原理是将任务分成多个小块,每个小块都可以在不同的线程上运行。然后,使用Task.Run方法将这些小块作为不同的任务提交给线程池。线程池会自动管理线程的创建和销毁,并根据系统资源的可用情况来自动调整线程数量,从而实现最大化利用CPU资源的效果。

● Task.Run(() => { });
● Task.Factory.StartNew(() => { });
● Task.Factory.ContinueWhenAll(new[] { task1, task2, task3 }, tasks =>
   {
       foreach (Task<string> task in tasks)
       {
           Console.WriteLine(task.Result);
       }
   });
● Task.WhenAll(  // 所有提供的任务已完成时,创建将完成的任务
       Task.Run(() => { }),
       Task.Run(() => { })
   );
● Task.WhenAny(  // 任何提供的任务已完成时,创建将完成的任务
       Task.Run(() => { }),
       Task.Run(() => { })
   );
● Task.WaitAll(  // 等待所有Task任务执行完毕,才会继续进行
       Task.Run(() => { }),
       Task.Run(() => { })
   );
● Task.WaitAny(  // 等待任一Task任务执行完毕,而不需要等待所有Task任务执行完毕
       Task.Run(() => { }),
       Task.Run(() => { })
   );
● Task.Delay(100); //创建将在时间延迟后完成的任务
● t.Start(); //启动Task
● t.Wait(); //等待Task完成执行过程
● Task.Yield(); //创建异步产生当前上下文的等待任务
● t.RunSynchronously()

  1. using System;
  2. using System.Linq;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using System.Web.Mvc;
  6. namespace Web.Controllers
  7. {
  8. public class HomeController : Controller
  9. {
  10. /// <summary>
  11. ///
  12. /// </summary>
  13. /// <returns></returns>
  14. public async Task<int> MethodAsync()
  15. {
  16. var today = await Task.FromResult<string>(DateTime.Now.DayOfWeek.ToString());
  17. int leisureHours;
  18. if (today.First() == 'S')
  19. leisureHours = 16;
  20. else
  21. leisureHours = 5;
  22. return leisureHours;
  23. }
  24. /// <summary>
  25. /// 异步打印传入的字符串
  26. /// </summary>
  27. /// <param name="str"></param>
  28. /// <returns></returns>
  29. public async Task<string> AsyncPringString(string str)
  30. {
  31. return await Task.FromResult<string>("刘德华");
  32. }
  33. /// <summary>
  34. ///
  35. /// </summary>
  36. /// <returns></returns>
  37. public async Task<string> ss()
  38. {
  39. return await Task.Run(() => PrintString());
  40. }
  41. /// <summary>
  42. /// 多线程执行后,执行另一个方法
  43. /// </summary>
  44. public void a()
  45. {
  46. var task1 = Task.Factory.StartNew(() => PrintString()).ContinueWith(
  47. task => { Console.WriteLine(task.Result.ToString()); }).ContinueWith(
  48. task => { Console.WriteLine("结束"); });
  49. }
  50. /// <summary>
  51. /// 等待所有线程结束
  52. /// </summary>
  53. public void b()
  54. {
  55. var task1 = Task.Factory.StartNew(() => PrintString());
  56. var task2 = Task.Factory.StartNew(() => PrintString());
  57. var task3 = Task.Factory.StartNew(() => PrintString());
  58. Task.WaitAll(task1, task2, task3);
  59. }
  60. /// <summary>
  61. /// 等待其中一个线程结束
  62. /// </summary>
  63. public void c()
  64. {
  65. var task1 = Task.Factory.StartNew(() => PrintString());
  66. var task2 = Task.Factory.StartNew(() => PrintString());
  67. var task3 = Task.Factory.StartNew(() => PrintString());
  68. Task.WaitAny(task1, task2, task3);
  69. }
  70. /// <summary>
  71. /// 等待所有线程结束执行的方法
  72. /// </summary>
  73. public void d()
  74. {
  75. var task1 = Task.Factory.StartNew(() =>
  76. {
  77. Thread.Sleep(3000);
  78. return "dummy value 1";
  79. });
  80. var task2 = Task.Factory.StartNew(() =>
  81. {
  82. Thread.Sleep(3000);
  83. return "dummy value 2";
  84. });
  85. var task3 = Task.Factory.StartNew(() =>
  86. {
  87. Thread.Sleep(3000);
  88. return "dummy value 3";
  89. });
  90. Task.Factory.ContinueWhenAll(new[] { task1, task2, task3 }, tasks =>
  91. {
  92. foreach (Task<string> task in tasks)
  93. {
  94. Console.WriteLine(task.Result);
  95. }
  96. });
  97. }
  98. private string PrintString()
  99. {
  100. return "Hello World!";
  101. }
  102. }
  103. }

2、在非异步api接口,调用异步方法()

  1. [HttpGet()]
  2. public IEnumerable<WeatherForecast> Get()
  3. {
  4. #region Wait()
  5. Task task = Task.Factory.StartNew(() =>
  6. {
  7. response = serviceClient.TestAsync(request).Result;
  8. });
  9. task.Wait();
  10. #endregion
  11. #region WaitAny
  12. //var task = Task.Factory.StartNew(() =>
  13. // response = serviceClient.TestAsync(request).Result
  14. //);
  15. //Task.WaitAny(task);
  16. #endregion
  17. #region Run Wait
  18. //Task.Run(() => response = serviceClient.TestAsync(request).Result).Wait();
  19. #endregion
  20. var rng = new Random();
  21. return Enumerable.Range(1, 5).Select(index => new WeatherForecast
  22. {
  23. Date = DateTime.Now.AddDays(index),
  24. TemperatureC = rng.Next(-20, 55),
  25. Summary = Summaries[rng.Next(Summaries.Length)],
  26. Test = response.Body.TestResult
  27. }).ToArray();
  28. }

3、在异步方法中,调用异步方法

  1. [HttpGet()]
  2. public async Task<string> Get()
  3. {
  4. var result = await serviceClient.TestAsync(request);
  5. return result.Body.TestResult;
  6. }

4、Thread
无参数

  1. public ActionResult FreeCallBack()
  2. {
  3. try
  4. {
  5. Thread thread1 = new Thread(new ThreadStart(test));
  6. thread1.IsBackground = true;
  7. thread1.Start();
  8. }
  9. catch (Exception)
  10. {
  11. }
  12. return View();
  13. }
  14. void test()
  15. {
  16. }

有参数

  1. public ActionResult FreeCallBack()
  2. {
  3. try
  4. {
  5. string conferenceid = "123456";
  6. Thread thread = new Thread(new ParameterizedThreadStart(Monitor));
  7. thread.IsBackground = true;
  8. thread.Start(conferenceid);
  9. }
  10. catch (Exception)
  11. {
  12. }
  13. return View();
  14. }
  15. void Monitor(object conferenceid)
  16. {
  17. }

5、ThreadPool 线程池
ThreadPool 类

一个应用程序最多只能有一个线程池;
ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池;
每排入一个工作函数,就相当于请求创建一个线程;
通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率

属性
CompletedWorkItemCount:获取迄今为止已处理的工作项数。
PendingWorkItemCount:获取当前已加入处理队列的工作项数。
ThreadCount:获取当前存在的线程池线程数。

方法
SetMaxThreads(Int32, Int32):设置可以同时处于活动状态的线程池的请求数目。 所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。
SetMinThreads(Int32, Int32):发出新的请求时,在切换到管理线程创建和销毁的算法之前设置线程池按需创建的线程的最小数量(最少存活的线程的数量)
GetMaxThreads(Int32, Int32):检索可以同时处于活动状态的线程池请求的数目。 所有大于此数目的请求将保持排队状态,直到线程池线程变为可用。
GetMinThreads(Int32, Int32):发出新的请求时,在切换到管理线程创建和销毁的算法之前检索线程池按需创建的线程的最小数量。
QueueUserWorkItem(WaitCallback):将方法排入队列以便执行。 此方法在有线程池线程变得可用时执行。
QueueUserWorkItem(WaitCallback, Object):将方法排入队列以便执行,并指定包含该方法所用数据的对象。 此方法在有线程池线程变得可用时执行。
*
*
*

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/104505?site
推荐阅读
相关标签
  

闽ICP备14008679号