列表初始化中异步方法调用意外并发问题的排查与解决
问题原因与解决方案
一、数据库调用不按顺序执行的原因与解决
原因
你看似是依次用await调用AsyncMethod1,但实际代码大概率触发了并行执行:
- 比如提前启动多个
AsyncMethod1任务后用Task.WhenAll统一等待,而非逐个await串行执行; - 或者
AsyncMethod1内部未正确await仓储层的GetCountByStatusAsync,导致任务提前进入完成状态,后续调用直接发起数据库查询; - 少数情况是数据库连接池调度导致后发起的查询先完成,但日志显示“调用并非按顺序执行”更可能是代码层面的并行触发。
解决办法
确保每个AsyncMethod1调用都在前一个完成后再执行,示例代码:
var resultObj = new ObjectToReturn(); // 逐个await,保证串行执行 resultObj.List1 = await AsyncMethod1(参数1); resultObj.List2 = await AsyncMethod1(参数2); resultObj.List3 = await AsyncMethod1(参数3);
同时检查AsyncMethod1内部,确保正确await仓储方法:
public async Task<YourListType> AsyncMethod1(YourParamType param) { // 必须await仓储层的异步方法,确保任务完成后再继续 var count = await _repository.GetCountByStatusAsync(param.Status); // 后续业务逻辑... return yourList; }
二、JSON自引用循环序列化错误的原因与解决
原因
要序列化的ObjectToReturn或其关联对象存在循环引用:比如ObjectToReturn的某个属性引用了自身,或者实体类的导航属性形成闭环(例如Order包含Customer,Customer又包含Orders集合)。JSON序列化器默认不处理这种循环依赖,因此抛出错误。
解决办法
1. 配置序列化器忽略循环引用
- 若使用Newtonsoft.Json:
var json = JsonConvert.SerializeObject(resultObj, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
- 若使用System.Text.Json(.NET Core 3.0+):
var json = JsonSerializer.Serialize(resultObj, new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.IgnoreCycles });
2. 使用DTO避免循环引用
创建专门的传输对象(DTO),只包含需要序列化的属性,剔除导致循环的导航属性:
public class ObjectToReturnDto { public YourListType List1 { get; set; } public YourListType List2 { get; set; } public YourListType List3 { get; set; } // 只保留需要返回的字段,不包含循环引用的属性 }
然后将ObjectToReturn映射为ObjectToReturnDto再序列化。
3. 标记忽略循环引用属性
用特性标记导致循环的属性,让序列化器跳过:
public class YourEntity { // 忽略这个导致循环的属性 [JsonIgnore] public ObjectToReturn Parent { get; set; } }
内容的提问来源于stack exchange,提问作者Fabio
相关产品推荐
相关产品推荐

