在异步方法并行任务中【SqlSugarScope】报错,这个不是线程安全的么? 返回

伪代码修改了一下,这里的update需要调用一些异步方法,所以需要声明async,还有ForEach中的task.run是希望对于每个model可以做异步并行处理,所以此处不希望使用await task.run static void Main(string[] args) { scope = new SqlSugarScope(new ConnectionConfig { IsAutoCloseConnection = true, DbType = DbType.MySql, ConnectionString = "*****" }); Update(); Console.ReadLine(); } static async Task Update() { await other_func_async(); scope.Queryable<TestModel>() .ToList() .ForEach(model => { Task.Run(async () => { try { await the_task_other_func(); model.status = 1; int isOk = await scope.Saveable(model).ExecuteCommandAsync(); logger.Info($"UpdateResult:{isOk}"); } catch (Exception ex) { logger.Error($"UpdateError:{ex}"); } }); }); await other_func_async2(); }
错误如下:
日志内容:UpdateError:SqlSugar.SqlSugarException: 中文提示 : 连接数据库过程中发
生错误,检查服务器是否正常连接字符串是否正确,实在找不到原因请先Google错误信息:
There is already an open DataReader associated with this Connection which must
e closed first..
English Message : Connection open error . There is already an open DataReader a
sociated with this Connection which must be closed first.
at SqlSugar.AdoProvider.GetDataReader(String sql, SugarParameter[] parameter
)
at SqlSugar.QueryableProvider`1.GetData[TResult](KeyValuePair`2 sqlObj)
at SqlSugar.QueryableProvider`1._ToList[TResult]()
at SqlSugar.QueryableProvider`1.ToList()
at SqlSugar.SaveableProvider`1.get_insertObjects()
at SqlSugar.SaveableProvider`1.LoadInsertable()
at SqlSugar.SaveableProvider`1.ExecuteCommand()
at SqlSugar.SaveableProvider`1.ExecuteCommandAsync()
at SqlSugarDemo2.Program.<>c__DisplayClass4_0.<<Update>b__1>d.MoveNext()
热忱回答(7)
-
Restraint VIP0
2022/1/17SqlSugarScope的初始化放在Main中也是一样报错。
这里当Update函数声明为async就会报错,去掉async并将await Task.CompletedTask 改为 return Task.CompletedTask则功能正常,但在业务中该函数中有其他异步业务调用所以需声明为async异步操作
0 回复 -
fate sta VIP0
2022/1/17没有await就不要用异步,正确代码如下:
using SqlSugar; using System; using System.Threading.Tasks; namespace OrmTest { class Program { static void Main(string[] args) { //for (int i = 0; i < 100; i++) //{ // Demo3_Insertable.Init(); //} Update().GetAwaiter().GetResult(); Console.ReadLine(); } static async Task Update() { var scope = new SqlSugarScope(new ConnectionConfig { IsAutoCloseConnection = true, DbType = DbType.MySql, ConnectionString =Config.ConnectionString }); var list = scope.Queryable<Order>() .ToList(); foreach (var model in list) { await Task.Run(async () => { try { int isOk = await scope.Saveable(model).ExecuteCommandAsync(); Console.WriteLine(model.Id); } catch (Exception ex) { } }); } } } }
0 回复 -
fate sta VIP0
2022/1/17虽然是线程安全不过你异步乱用还是可能会出错的
0 回复 -
Restraint VIP0
2022/1/17@fate sta:在业务中该函数中有其他异步业务调用所以需声明为async异步操作,这里await Task.CompletedTask;其实就是调用其他异步方法的替代,只是为了展示,其实你可以当我这里是await other_func();
还有就是Task.Run这里我是希望可以并行处理的所以不能用await阻塞,因为包含一些其他的业务操作,业务操作完之后才会Saveable(model).ExecuteCommandAsync
0 回复 -
fate sta VIP0
2022/1/17@Restraint: https://www.donet5.com/Home/Doc?typeId=2349 异步有异步用法
0 回复 -
Restraint VIP0
2022/1/17@fate sta:这里的异步方式我看过了,
此处使用的是SqlSugarClient而不是SqlSugarScope,所以需要自己在相关的task中new SqlSugarClient
这个示例中的不一样的在于tolist使用tolistasync,这里的异步区别不大,使用后依然报错,对于下面不一样在于task.whenall,这里是为了等待所有子任务完成从而进行后续操作,而我这里每个task之间互不影响,后续操作并不依赖所有task结束,而且接入whenall报错依旧
综上结论,感觉这里的问题可能在于SqlSugarScope对于task的支持有限,也可能是其他我没有发现的点位有问题
0 回复 -
fate sta VIP0
2022/1/17@Restraint:底层驱动就这样和sqlsugarscope并没关系,TaskWhenAll里面的东西没办法去处理,所以只能new , 像sqlserver这块就支持非常好不需要new就能taskwhenall
0 回复