在多个数据库插入时,控制台应用程序的ThreadAbortException

本文关键字:控制台 应用程序 ThreadAbortException 数据库 插入 | 更新日期: 2023-09-27 18:14:57

如果我尝试在控制台应用程序中使用线程一次执行>100个数据库插入,我会得到以下错误。根据目前的架构,我需要一次插入一个记录。对于较少数量的记录(10-30),不会发生错误。一次插入这么多记录会产生这个问题吗?

代码类似于:

foreach (MyObject myObject in myObjectCollection)
{
   var database = new SqlDatabase(connectionString);
   using (DbCommand command = database.GetStoredProcCommand(storedProcedureName))
   { 
         // Create parameters from myObject
         // Add parameters to the command object         
         database.ExecuteNonQuery (command);
   }    
}

错误:

System.Threading.ThreadAbortException: Thread was being aborted.    
 at SNIReadSync(SNI_Conn* , SNI_Packet** , Int32 )    
 at SNINativeMethodWrapper.SNIReadSync(SafeHandle pConn, IntPtr& packet, Int32 timeout)    
 at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)    
 at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()    
 at System.Data.SqlClient.TdsParserStateObject.ReadBuffer()    
 at System.Data.SqlClient.TdsParserStateObject.ReadByte()    
 at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)    
 at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)    
 at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)    
 at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)    
 at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)    
 at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()    
 at Microsoft.Practices.EnterpriseLibrary.Data.Database.DoExecuteNonQuery(DbCommand command)    
 at Microsoft.Practices.EnterpriseLibrary.Data.Database.ExecuteNonQuery(DbCommand command)

在多个数据库插入时,控制台应用程序的ThreadAbortException

连接池资源即将用完。更改循环外的分配和创建。

我已经更新了答案,以显示SqlDatabase打开的连接的显式关闭需要在finally语句中执行:

   SqlDatabase database = new SqlDatabase(connectionString);
   try {
      using (DbCommand command = database.GetStoredProcCommand(storedProcedureName)) {
         // Create parameters from myObject
        foreach (MyObject myObject in myObjectCollection)
        { 
             // Add parameters to the command object         
             database.ExecuteNonQuery (command);
       }
      } 
   } finally {
      if (database != null) {
         // Do whatever is necessary here to explicitly close the connection to the database
      }
   }

是否可能触发DataBaseTimeout?试着在客户端设置一个更高的TimoutNumber

你碰巧有Asynchronous Processing=true(或只是async=true)在你的连接字符串?如果有,请尝试删除它。

另外,您是否尝试使用"纯"ADO.NET实现此功能?

线程是后台线程吗?如果是,Main()可能在执行过程中返回,这会中止后台线程。

如果您正在使用EF,这里有一个方法来运行任何DB过程,确保连接是关闭的:

void EnsureClose<TObjectContext>(Action<TObjectContext> dbAction) where TObjectContext : ObjectContext, new()
    {
        using (var objContext = new TObjectContext())
        {
            try
            {
                dbAction(objContext);
            }
            finally
            {
                objContext.Connection.Close();
            }
        }
    }