C# 当类的单个实例正在等待任务时会发生什么?

C# 当类的单个实例正在等待任务时会发生什么?,c#,multithreading,asynchronous,.net-core,C#,Multithreading,Asynchronous,.net Core,编辑:将“单实例”更改为“单实例”,因为它不是真正的单实例 假设在应用程序中有一个DataAccess类作为单个实例运行。这一个使用MongoDB,但它可以应用于任何具有内部异步调用的对象 public class DataAccess { private IMongoDatabase _database; public DataAccess(IMongoClient client) { _database = client.GetDatabase("m

编辑:将“单实例”更改为“单实例”,因为它不是真正的单实例

假设在应用程序中有一个
DataAccess
类作为单个实例运行。这一个使用MongoDB,但它可以应用于任何具有内部异步调用的对象

public class DataAccess
{
    private IMongoDatabase _database;

    public DataAccess(IMongoClient client)
    {
        _database = client.GetDatabase("myDataBase");
    }

    public virtual async Task<IEnumerable<User>> GetUsers()
    {
        var collection = _database.GetCollection<User>("users").Find("{}");
        return await collection.ToListAsync();
    }
}
然后它被注入控制器

假设我让thread1调用DataAccess.GetUsers(),它正在等待ToListAsync方法的结果。现在,thread2在thread1等待时调用DataAccess.GetUsers()。会发生什么

  • DataAccess实例是否被thread1锁定,因此thread2在thread1完成之前无法开始执行GetUsers方法
  • DataAccess实例是否可用且thread2运行同一集合。在thread1也运行该方法时查找方法
  • DataAccess实例是否可用,但thread2在运行到已在运行的ToListSync方法时会进入睡眠状态

选项2:singleton可用,thread2运行相同的集合。在thread1也运行它时查找方法


这就是为什么在编写单例时,必须确保代码可以安全地并发运行或以renterent方式运行。通常这需要在资源周围放置一个
,将其从选项2转换为选项1。

对不起,单例在哪里?从你的代码中,我可以调用DataAccess构造函数任意次数。我现在就更新它。DataAccess是由控制器调用的单例。除非给定类型在其文档中明确指出它是设计为从多个线程并行调用的,并且如果这样做,行为会是什么,假设它不是为从多个线程调用而设计的,如果您这样做,它的行为将意外且错误。@Micteu不,它不是单线程。它有一个公共构造函数。绝对可以有多个实例。你个人不打算创建多个并不意味着它是一个单体。你强迫它只有一个是使它成为单例的原因,而你没有这样做。数据访问可能不会因为被共享而受到影响,而是IMongoClient在线程之间共享,这可能不是线程安全的。谢谢你满足了我的好奇心,而不是试图让我觉得自己很愚蠢,因为我的措辞有点不恰当。
services.AddSingleton<DataAccess, DataAccess>();