c# - 多线程环境下的mysql连接器

标签 c# mysql

我有一个连接到 mysql 服务器以获取数据的 c# 服务器。这个 c# 服务器是游戏的后端服务器,它为当前登录的每个玩家都有一个开放线程。我如何进行 mysql 连接,每个线程都有一个开放连接?对所有线程使用锁定的单个连接?

我在某处读到有一个“线程池”。真的吗?如果是这样,这是正确的使用方法吗:

using(var conn = new MySqlConnection(DatabaseHelper.getConnectionString()))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT username FROM characters WHERE id=1";
    using (var reader = cmd.ExecuteReader())
    {
        while (reader.Read())
        {
            user = reader.GetString("username");
        }
    }
}

最佳答案

我认为您在这里混淆了两种不同的资源;您可能确实希望为每个登录的玩家打开一个线程(实际上是一个进程),但这并不意味着您应该为每个玩家不断打开一个到数据库的连接,因为数据库连接、文件句柄等不受管理资源,并应在您用完它们后立即释放。

对 C# 线程有很好的介绍和解释 here .

您应该只在需要时才打开与数据库的连接。这意味着您的数据访问类可以多次实例化(这是最简单的设计),每次都有自己的连接。如果你使用 connection pooling ,我觉得你实际上可能一直在问,那么你会进一步受益。转向静态数据库连接设计(其中许多人共享相同的 dao 类)可能会出现更多问题,因为您可能必须同步某些资源,确保某些变量只能通过锁定或类似方式按顺序访问,等等。

您可以阅读更多相关信息 here例如。微软也谈连接池的好处here .

您上面的代码是连接数据库的一个很好的起点,包括您要关闭的 using 语句,并在完成连接后立即处理它;您还可以考虑以下改进:

using(var conn = new MySqlConnection(DatabaseHelper.getConnectionString())) 
{
  using (var cmd = conn.CreateCommand()) 
  { 
      conn.Open(); 
      cmd.CommandType = CommandType.Text;
      //Parameterize your queries!
      cmd.CommandText = "SELECT username FROM characters WHERE id=?"; //Use ? as placeholder for parameters, and add parameters in the order they appear in your query.
      cmd.Parameters.Add(new MySqlParameter("@userid", MySqlDbType.Int, userid));

      using(IDataReader reader = cmd.ExecuteReader())
      { 
          //You should only expect one record. You might want to test for more than 1 record.
          if (reader.Read()) 
          { 
              user = reader.GetString(reader.GetOrdinal("username")); //Think also about null value checking.
          } 
      } 
  }
}

您可能有一个 DAO 类或用户类的方法来执行此操作。例如,如果它是针对用户的方法,您可能会这样做:

User myUser = new User(7);
myUser.Load(); 

在 Load 内部,您可能调用的方法之一是 PopulateFromDB(),它将包含上述代码,并将加载该用户的所有属性。您可能还有一个执行相同操作的 DAO 类:

UserLoader loader = new UserLoader();
string userName = loader.GetUserName(int userId);

这将使用上面示例中的代码返回用户名。我更喜欢这种方法在像 User 这样的类上,因为它在逻辑上与它相连。但是,您随后冒着将 DAO 逻辑与用户业务逻辑混合的风险,这本身就是一个主题。

与其编写大量此类数据访问逻辑,不如考虑查看某种形式的框架,例如 ORM 或类似的框架 - 这 question has already been answered for MySql所以。这还可以为您节省大量时间和精力,让您可以专注于设计。

关于c# - 多线程环境下的mysql连接器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8458024/

相关文章:

c# - 从一个..函数填充一个列表框?

mysql - 如何查看准备好的语句或者我应该放弃动态表名称吗?

java - 为什么 Spring Boot MVC 总是从我的表单返回 null 值?

mysql - 尽管没有外键,但出现 "Foreign key contraint"错误消息

C# 更改表并以编程方式添加列 ASP.Net 和 SQL Server

c# - 比赛结果平局,如何在基座上列出两个名字?

c# - 使用 DTO 和 BO

c# - ObservableCollection CollectionChanged 更新数据网格

php - PDO 连接测试

mysql 获取最后 N strip 有 MAX(日期) 的记录