首页 > 其他分享 >.net List.ForEach内部Async/Await 异步的问题

.net List.ForEach内部Async/Await 异步的问题

时间:2023-10-07 10:34:52浏览次数:36  
标签:Do After Console Thread Await List Item ForEach Before

在开发异步的WebApi时,发现一个线程并发错误,起初以为SqlSugar问题。后来,经查是代码写的问题。但此问题,不遇到,不会知晓,只有异步才会出现此问题。

这种问题,也发生在JavaScript下,代码逻辑是一样的。参看这篇:https://advancedweb.hu/how-to-use-async-functions-with-array-foreach-in-javascript/

一般同步模式,ForEach会对每个元素同步执行,上一个执行完成才执行下一个。List.ForEach(x=>{

  Do(x);

});

但是,异步模式不是这样,对每个元素不等待执行完成,会进入下个一元素。如果Do内操作数据库,这会造成多线程相关错误。List.ForEach(async x=>{

  await Do(x);

});

这时,可以用foreach(var x in List){ await Do(x); } 此模式会对List元素一个一个同步执行。

相关代码,我做了个样例,.Net 7控制台:

 1 /*第一种模式 ForEach内部,每个循环,不等待上一步完成,一起执行*/
 2 /*
 3  * Expected output:
 4 Item:1 Before. Thread:1
 5 Item:2 Before. Thread:1
 6 Item:3 Before. Thread:1
 7 Finish. Thread:1
 8 Do:3 Thread:9
 9 Item:3 After. Thread:9
10 Do:2 Thread:9
11 Item:2 After. Thread:9
12 Do:1 Thread:9
13 Item:1 After. Thread:9
14 */
15 //new int[] { 1, 2, 3 }.ToList().ForEach(async x =>
16 //{
17 //    Console.WriteLine($"Item:{x} Before. Thread:{Thread.CurrentThread.ManagedThreadId}");
18 //    await A.Do(x);
19 //    Console.WriteLine($"Item:{x} After. Thread:{Thread.CurrentThread.ManagedThreadId}");
20 //});
21 
22 /*第二种模式 foreach内部,每个循环,等待上一步完成,同步执行*/
23 /*
24  * Expected output: 
25 Item:1 Before. Thread:1
26 Do:1 Thread:4
27 Item:1 After. Thread:4
28 Item:2 Before. Thread:4
29 Do:2 Thread:4
30 Item:2 After. Thread:4
31 Item:3 Before. Thread:4
32 Do:3 Thread:4
33 Item:3 After. Thread:4
34 Finish. Thread:4
35  */
36 foreach (var x in new int[] { 1, 2, 3 })
37 {
38     Console.WriteLine($"Item:{x} Before. Thread:{Thread.CurrentThread.ManagedThreadId}");
39     await A.Do(x);
40     Console.WriteLine($"Item:{x} After. Thread:{Thread.CurrentThread.ManagedThreadId}");
41 
42 }
43 
44 Console.WriteLine($"Finish. Thread:{Thread.CurrentThread.ManagedThreadId}");
45 Console.ReadKey();
46 
47 class A
48 {
49       
50     public static async Task Do(int a)
51     {
52         await Task.Delay((10 - a) * 1000);
53         Console.WriteLine($"Do:{a} Thread:{Thread.CurrentThread.ManagedThreadId}");
54     } 
55 }

 

标签:Do,After,Console,Thread,Await,List,Item,ForEach,Before
From: https://www.cnblogs.com/wigis/p/17745737.html

相关文章

  • 界面组件DevExpress WinForms v23.1 - TreeList、UI模板全新升级
    DevExpressWinForms拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!DevExpressWinForm 控件已正式发布v23.1版本,此版......
  • 2023-10-06 useState数据渲染不同步==》async await
    业务:点击按钮增加数据并渲染出来。框架:antd+ts+react。原来写法:const[tagData,setTagData]=useState<Array<number>>([]);点击事件://添加标签constaddTag=()=>{letarr:(number)[]=[];arr=tagData;arr.push(Math.floor(Math.random()......
  • forEach中return会退出循环吗 (改)
    forEach循环在JavaScript中的forEach循环中使用return语句,并不会退出或终止循环,forEach循环会继续执行完剩余的所有迭代。forEach循环中的return语句只会从当前的迭代回调函数中返回,而不会中断整个循环。举例来说:constarray=[1,2,3,4,5];array.forEach(num=>{if......
  • ArrayList的线程安全问题简述,以及如何优化
    问题:创建一个ArrayList,然后创建两个线程,每个线程for循环1000次向公共的List里面添加数据,在一个线程读取List当前的大小之后,另一个线程可能已经对List进行了修改。这样就可能导致数据的不一致性,例如一个线程读取到的List大小已经被另一个线程修改了,因此,在这个案例中,最终的列表大小......
  • JavaSE(08) - 集合 - ArrayList
    JavaSE(08)-集合-ArrayListp111ArrayList基本使用创建集合对象,泛型:限定集合中的数据类型.在jdk7中,后面的<>中可以不写数据类型.集合在底层做了一些处理,打印对象不是地址值,而是集合中存储的内容.publicclassArrayListBasic{publicstaticvoidmain......
  • 关于Async、Await的一些知识点
    在ASP.NETCore中,当一个HTTP请求到达服务器时,它会被分配给线程池中的一个线程来处理。该线程会执行相应的Controller方法。如果这个方法是一个异步方法并且使用了await关键字,那么在await的代码执行完毕之前,这个线程会被释放回线程池,可以用来处理其他的HTTP请求。当await的代码执......
  • Mybatis查询报错 foreach 子查询 (invalid comparison)
    Mybatis查询报错invalidcomparison:java.lang.Stringand[Ljava.lang.String;原因去掉黄色部分<iftest="null!=businessTypeand''!=businessType">  andt.businessTypein     <foreachcollection="businessType"......
  • Nginx listen 监听端口详解
    listen指令监听端口:listenaddress:port[default|default_server|[backlog=num|rcvbuf=size|sndbuf=size|accept_filter|deferred|bind|ipv6only=[on|off]|ssl]];默认:listen80配置块:server含义指定服务监听的地址,如果使用IP协议,则可以包......
  • Jenkins List Git Branches插件 构建选择指定git分支
    ListGitBranchesParameter|JenkinspluginAddsabilitytochoosefromgitrepositoryrevisionsortagshttps://plugins.jenkins.io/list-git-branches-parameter/1、安装组件  ListGitBranches2、验证功能1)新建任务 2)新增构建参数 3)选择git仓库我这里选择gitee,其他......
  • list接口
    13.3.1List接口的定义publicinterfaceList<E>extendsCollection<E>13.3.2List接口的常用子类如果要使用List接口进行操作,就必须依靠子类实现对象的实例化操作,而在实际开发中List子接口有 ArrayList, Vector 和 LinkedList3个常用子类。1.新的子类:ArrayListArra......