在多个数据库插入时,控制台应用程序的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)
连接池资源即将用完。更改循环外的分配和创建。
我已经更新了答案,以显示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();
}
}
}