我的静态DAL中的MySQL线程问题

时间:2012-03-02 12:15:24

标签: c# mysql

我在我正在重写的旧C#应用程序中使用MySQL .Net库。数据访问层相当过时,但我正在努力充分利用它。但现在我遇到了一些非常讨厌的线程问题。

我有一系列约20个用于处理报告的Select语句。它们需要大约5秒钟才能完成,我在Select语句运行时显示进度条。我通过简单的ThreadPool调用启动操作:

[后期编辑:由于我的用户界面中的错误,我将下面的方法称为两次 - 会发生这种情况 - 但这并没有使问题贬值,只是解释了为什么我的主题与每个人竞争其他。]

ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateChart));
  • 有时会有效。
  • 有时它会因“可能的IO流竞争条件”而崩溃。
  • 有时它会因“连接应该是开放且有效”而崩溃。
  • 有时会因为“对象引用没有设置......”而崩溃。

我的DAL中的所有类都是Static,因为我认为这是提高性能的好方法(不必为每个小操作创建新的类实例)。

我所有的DAL类都使用相同的“root”DAL类来构建Connections:

public static class MySQLConnectionBuilder
{

private static MySqlConnectionStringBuilder ConnectionStringBuilder = new MySqlConnectionStringBuilder();

//I'm initializing the ConnectionStringBuilder with my server password & address.

public static MySqlConnection GetConnection ()
{
  return new MySqlConnection(ConnectionStringBuilder.ConnectionString);
}

}

我的所有DAL类都具有与崩溃功能类似的功能。崩溃函数如下所示:

public static STDS.UserPresence.user_presenceDataTable GetPresence (int aUserID, DateTime aStart, DateTime aEnd)
{
  ta.Connection = MySQLConnectionBuilder.GetConnection();
  ds = ta.GetPresenceForUserBetweenDates(aUserID, aStart, aEnd);
  ta.Connection.Close();
  return ds;
}

想法?改进提示?如果我切换到更面向对象(实例驱动)的DAL,那么线程问题会消失吗?

1 个答案:

答案 0 :(得分:1)

该行

ta.Connection.Close()

关闭最后分配给ta.Connection的连接 - 并不总是在同一个线程中创建的连接。这可能会关闭当前正在另一个线程中运行查询的连接。

如果您想快速确定这是否正在发生,请使用类ta中的[ThreadStatic]属性标记连接变量,指向:

[ThreadStatic]
private static MySqlConnection connection;

我不会将这种方法用于你的最终解决方案,因为它可能导致GC不收集它们。

一个简单的解决方案(对于 问题,我无法确定您的类是否存在其他多线程问题)是将连接作为参数添加到每个DAL方法中,允许您删除全球班Connection

public static STDS.UserPresence.user_presenceDataTable GetPresence (int aUserID, DateTime aStart, DateTime aEnd)
{
  using (MySqlConnection connection = MySQLConnectionBuilder.GetConnection())
  {
      ds = ta.GetPresenceForUserBetweenDates(connection, aUserID, aStart, aEnd);
      return ds;
  }
}

线程问题永远不会消失 - 它们需要引起注意。如果您不确定发生了什么,请忘记轻微的性能提升(如果查询需要5秒,那么使用静态类的任何可能的性能增益都将低于1%)。