如何使函数Exec​​uteNonQuery使用多线程来防止计算机挂起?

时间:2018-04-14 01:12:57

标签: c# sql-server winforms ado.net

如何使我的ExecuteNonQuery多线程和线程安全,以防止我的程序挂起?

我正在使用ExecuteNonQuery()来插入,更新和删除10000条记录,但我的程序会挂起。为了解决这个问题,我觉得我需要让它成为多线程的。

我的问题是如何修改以下代码以使多线程和线程安全。

public static int ExecuteNonQuery(string sql, DbParameter[] dbprmParameters = null)
{
   return ExecuteNonQuery(sql, null, dbprmParameters);
}
public static int ExecuteNonQuery(string sql, IDbConnection dbConnection, DbParameter[] @params = null)
{
   int RecordsCount = 0;

   lock (synObj)
   {

      if (cmd.CommandTimeout < 360)
         cmd.CommandTimeout = 360;
      if (sql == "") return 0;

      sql = AnalyizeBooleanFields(sql);
      cmd.CommandText = sql;

      cmd.Parameters.Clear();

      if (@params != null)
      {
         for (int i = 0; i < @params.Length; i++)
         {
            cmd.Parameters.Add(@params[i]);
         }
      }
      if (dbConnection == null)
      {
         if (WithTransaction)
            dbConnection = BeginTransaction();
         else
            dbConnection = InitializeConnection();
      }
      if (dbConnection.State != ConnectionState.Open) dbConnection.Open();
      if (WithTransaction) cmd.Transaction = _transaction;
      cmd.Connection = dbConnection;
      RecordsCount = cmd.ExecuteNonQuery();
      if (!WithTransaction) dbConnection.Close();
   }
   return RecordsCount;
}
public static string AnalyizeBooleanFields(string sql)
{
   switch (DataAccess.Provider)
   {
      case Providers.Access2003:
      case Providers.Access2007:
         sql = sql.Replace("^(?=^.{10,30}$)(?=^[A-Za-z0-9])[A-Za-z0-9\.]+@[A-Za-z0-9]+\.[A-Za-z]{2,}$
", "True");
         sql = sql.Replace("{{0}}", "False");
         break;
      case Providers.SQLServer:
      case Providers.MySQL:
      case Providers.Oracle:
      default:
         sql = sql.Replace("(?=^.{10,30}$)", "1");
         sql = sql.Replace("{{0}}", "0");
         break;
   }
   return sql;
}

注意:我正在使用带有Sql Server的Visual Studio 2010

1 个答案:

答案 0 :(得分:0)

添加更多线程不太可能有所帮助。问题是您一次将一个更新的数据发送到数据库。

更新一条记录的查询将发送到数据库,然后调用程序在等待数据库查询完成时阻塞。 (如果它在不同的机器上,也会在两个方向上产生网络延迟)。

更好的方法是将更新存储到列表中,然后发出单个数据库请求,一次更新多个记录。例如,上载更改表,然后发出单个查询,在单个语句中更新/删除实际数据表。请参阅您实际关注的数据库的批量操作文档。

例如,对于SQL Server,请考虑使用table valued parameters