You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C#类初始化器中调用多个异步操作是否会引发并发问题?

问题分析

给定C#类:

public class MyData
{
    public int Value1 { get; set; }
    public int Value2 { get; set; }
}

采用如下方式实例化并初始化:

var myInstance = new MyData
{
    Value1 = await MyFirstAsync(),
    Value2 = await MySecondAsync()
};

假设MySecondAsync()与MyFirstAsync()依赖同一非线程安全资源,请问这种写法是否会引发并发问题,或存在其他需规避的潜在问题?


回答

这种写法不会引发并发问题,核心原因是对象初始化器里的赋值操作是串行执行的:

  • 先执行Value1 = await MyFirstAsync():调用MyFirstAsync()并等待它完全执行完毕,这段时间里MySecondAsync()不会被启动
  • 只有当MyFirstAsync()执行完成、给Value1完成赋值后,才会执行Value2 = await MySecondAsync(),等待MySecondAsync()完成并赋值

因为两个异步方法是先后执行,不会同时运行,所以它们不会同时访问那个非线程安全资源,自然不会触发并发冲突。

潜在需要注意的点

  1. 异常场景的临时对象处理:如果初始化过程中MySecondAsync()抛出异常,此时MyData对象已经被创建且Value1已赋值,但这个对象不会被赋值给myInstance,最终会被GC回收,不会出现“部分初始化的实例被误用”的情况,无需额外担心。
  2. 性能优化的风险:如果想通过并发执行两个异步方法提升性能,直接改用Task.WhenAll的写法会触发并发访问非线程安全资源的问题,比如:
    var task1 = MyFirstAsync();
    var task2 = MySecondAsync();
    await Task.WhenAll(task1, task2);
    var myInstance = new MyData { Value1 = task1.Result, Value2 = task2.Result };
    
    这种写法会让两个方法同时运行,此时必须给非线程安全资源添加同步锁(比如lock)来避免并发冲突。

内容的提问来源于stack exchange,提问作者R26

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 21:45:55