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

时间:2011-11-18 00:40:17

标签: c# multithreading

如果我尝试使用控制台应用程序中的线程一次执行一次> 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)

5 个答案:

答案 0 :(得分:2)

您将耗尽连接池资源。更改循环外的分配和创建。

<强>更新

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

   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
      }
   }

答案 1 :(得分:0)

您是否可以触发DataBaseTimeout?尝试在客户端中添加更高的TimoutNumber。

答案 2 :(得分:0)

您的连接字符串中是否恰好有Asynchronous Processing=true(或只是async=true)?如果您这样做,请尝试将其删除。

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

如果您使用EF,这里有一个方法来运行任何数据库程序,确保连接已关闭:

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