<ApplicationData> <TraceData> <DataItem> <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error"> <TraceIdentifier>http://msdn.microsoft.com/zh-CN/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier> <Description>Throwing an exception.</Description> <AppDomain>TC.WCF.HostINSDB.exe</AppDomain> <Exception> <ExceptionType>System.Net.Sockets.SocketException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType> <Message>由于线程退出或应用程序请求,已中止 I/O 操作。</Message> <StackTrace> at System.ServiceModel.Channels.SocketConnection.HandleReceiveAsyncCompleted() at System.ServiceModel.Channels.SocketConnection.OnReceiveAsync(Object sender, SocketAsyncEventArgs eventArgs) at System.ServiceModel.Channels.SocketConnection.OnReceiveAsyncCompleted(Object sender, SocketAsyncEventArgs e) at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e) at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncFailure(SocketError socketError, Int32 bytesTransferred, SocketFlags flags) at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) </StackTrace> <ExceptionString>System.Net.Sockets.SocketException (0x80004005): 由于线程退出或应用程序请求,已中止 I/O 操作。</ExceptionString> <NativeErrorCode>3E3</NativeErrorCode> </Exception> </TraceRecord> </DataItem> </TraceData> </ApplicationData>
<ApplicationData> <TraceData> <DataItem> <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error"> <TraceIdentifier>http://msdn.microsoft.com/zh-CN/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier> <Description>Throwing an exception.</Description> <AppDomain>TC.WCF.HostINSDB.exe</AppDomain> <Exception> <ExceptionType>System.Net.Sockets.SocketException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType> <Message>远程主机强迫关闭了一个现有的连接。</Message> <StackTrace> at System.ServiceModel.Channels.SocketConnection.HandleReceiveAsyncCompleted() at System.ServiceModel.Channels.SocketConnection.OnReceiveAsync(Object sender, SocketAsyncEventArgs eventArgs) at System.ServiceModel.Channels.SocketConnection.OnReceiveAsyncCompleted(Object sender, SocketAsyncEventArgs e) at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e) at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncFailure(SocketError socketError, Int32 bytesTransferred, SocketFlags flags) at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP) </StackTrace> <ExceptionString>System.Net.Sockets.SocketException (0x80004005): 远程主机强迫关闭了一个现有的连接。</ExceptionString> <NativeErrorCode>2746</NativeErrorCode> </Exception> </TraceRecord> </DataItem> </TraceData> </ApplicationData>
满满的都是这种异常。
还有大面积的DbDataReader的异常
获取数据是这样的 GetUserPowerList方法是这样的
using (DbDataReader reader = DBHelperSQL.ExecuteProcedure("prLM_PageUserPower", parameters)) { while (reader.Read()) { INS_UserPower model = new INS_UserPower(); #region Model model.Id = (int)reader["id"];//主键id,存储过程如果返回的有数据,这个id列是肯定有的 } }
prLM_PageUserPower 存储过程代码是这样的
SELECT * FROM tbgroup WHERE userid = @Id
<Description>Handling an exception. Exception details: System.IndexOutOfRangeException: id at System.Data.ProviderBase.FieldNameLookup.GetOrdinal(String fieldName) at System.Data.SqlClient.SqlDataReader.GetOrdinal(String name) at System.Data.SqlClient.SqlDataReader.get_Item(String name) at TC.WCF.DALSQLServer.INS.INS_UserPowerDAL.GetUserPowerList(String strWhere, String strOrder) at TC.WCF.DataService.INS.INSDbService.GetUserPowerList(String strWhere, String strOrder) at SyncInvokeGetUserPowerList(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</Description> <AppDomain>TC.WCF.HostINSDB.exe</AppDomain> <Exception> <ExceptionType>System.IndexOutOfRangeException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType> <Message>id</Message> <StackTrace> at System.Data.ProviderBase.FieldNameLookup.GetOrdinal(String fieldName) at System.Data.SqlClient.SqlDataReader.GetOrdinal(String name) at System.Data.SqlClient.SqlDataReader.get_Item(String name) at TC.WCF.DALSQLServer.INS.INS_UserPowerDAL.GetUserPowerList(String strWhere, String strOrder) at TC.WCF.DataService.INS.INSDbService.GetUserPowerList(String strWhere, String strOrder) at SyncInvokeGetUserPowerList(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet) </StackTrace> <ExceptionString>System.IndexOutOfRangeException: id at System.Data.ProviderBase.FieldNameLookup.GetOrdinal(String fieldName) at System.Data.SqlClient.SqlDataReader.GetOrdinal(String name) at System.Data.SqlClient.SqlDataReader.get_Item(String name) at TC.WCF.DALSQLServer.INS.INS_UserPowerDAL.GetUserPowerList(String strWhere, String strOrder) at TC.WCF.DataService.INS.INSDbService.GetUserPowerList(String strWhere, String strOrder)//这里这个方法获取 at SyncInvokeGetUserPowerList(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</ExceptionString> </Exception>
model.Id = (int)reader["id"];
异常是这里抛出的,找不到名称为 id 的列。如果你肯定返回的列中有名称 id 的列,而代码告诉你没有,这是不是很奇怪?你是觉得程序故意跟你作对,还是你考虑问题的出发点错了?
while(reader.read())
{
}如果有数据返回,这里肯定有这一列
这个reader的问题跟这个http://www.cnblogs.com/caca/archive/2008/04/03/1136815.html帖子的问题是一样的,也是偶尔有这个异常,也有可能突然爆发,把wcf服务都给搞死了。
@Rookier: 你的代码的问题,我给你贴个代码,你把你原来的逻辑替换掉:
GetUserPowerList()
{
using(SqlConnection conn = new SqlConnection())
{
SqlCommand cmd = new SqlCommand(conn);
cmd.CommandTxt = "";
conn.Open();
using ( SqlDataReader rdr = cmd.Exectue())
{
while(rdr.Read())
{
INS_UserPower model = new INS_UserPower();
model.Id = (int)reader["id"];
}
rdr.Close();
}
conn.Close();
}
}
@Launcher: 这个用的sqlhelp
public DbDataReader ExecuteProcedure(string procedureName, DbParameter[] parms, int seconds) { cmdType = CommandType.StoredProcedure; cmdText = procedureName; cmdParms = parms; cmdTimes = seconds; CommandBehavior cmdBehavior = CommandBehavior.CloseConnection; try { //prepare Prepare(); //execute dr = cmd.ExecuteReader(cmdBehavior); return dr; } catch (DbException ex) { CloseConn(); throw new Exception(procedureName + ex.Message, ex); } } private void Prepare() { conn = DataFactory.CreateConnection(); cmd = DataFactory.CreateCommand(); da = DataFactory.CreateDataAdapter(); if (this.conn.State == ConnectionState.Closed) { conn.ConnectionString = ConnectionString; this.conn.Open(); } else if (conn.State != ConnectionState.Open) { conn.Close(); conn.Open(); } cmd.Connection = conn; cmd.CommandText = cmdText; cmd.CommandTimeout = cmdTimes; cmd.CommandType = cmdType; if (trans != null) { cmd.Transaction = trans; } cmd.Parameters.Clear(); if (cmdParms != null) { foreach (DbParameter parm in cmdParms) { cmd.Parameters.Add(parm); } } cmd.Prepare(); }
@Rookier: 知道我为什么要让你像我那样写吗?我其实是在提醒你,注意在 DbConnection 上的多线程安全问题,而你贴出了这样的代码,你让我看到了什么,看到了你的成员变量 conn ,cmd,dr,da,全都是成员变量,你如何保证线程安全?
根据我的印象,微软在示例代码中经常使用的 SqlHelper 可不是这样的,所以请你修改成我写的那样,能够清楚的表明各个变量的生命周期和线程安全性,当所有这些因素都排除后,如果还会出现 IndexOutOutRange 异常,你才应该抓耳挠腮。
唉,前辈们写的代码让人心惊肉跳,数据库用单例,总觉得哪里怪怪的。
private string _connString; //链接字符串 TC.Framework.Data.DbBase DBHelperSQL; //创建数据库帮助对象,还tm是全局变量,说好的线程安全呢 private static INS_UserInfoDAL ins_userinfoDAL = null; //创建一个自身对象 private static readonly object syncRootNet = new object(); public string ConnectionString { get { return _connString; } set { _connString = value; } } private INS_UserInfoDAL() { _connString = ConfigurationManager.ConnectionStrings["TCGCDXdb"].ConnectionString; DBHelperSQL = new TC.Framework.Data.DbSqlServer(_connString); } /// <summary> /// 单例返回DAL 的实例 /// </summary> /// <returns></returns> public static INS_UserInfoDAL GetInstance() { if (ins_userinfoDAL == null) { lock (syncRootNet) { if (ins_userinfoDAL == null) { ins_userinfoDAL = new INS_UserInfoDAL(); } } } return ins_userinfoDAL; }
DbConnection的任何公共静态成员都是线程安全的,但不保证所有实例成员都是线程安全的。 数据库引擎有各种实现策略,对于某些引擎,当一个DBConnection被一个静态游标(例如某种DBReader)锁住的时候,此时你不关闭这个Reader,直接将DBConnection用于另外一个查询,数据库引擎就会告诉你这个DBConnection不能用于其它查询(否则现有的游标就被毁了),这跟单线程、多线程毫无关系.
@Rookier: 你要认为你的理解是对的,我也没办法,反正我是写不出你们这种代码,我水平有限。
@Launcher: 代码是之前的人写的,我觉得数据库这里用单例就有很大的问题,哪哪都是reader,这个不是一直占用数据库链接的。。唉。。改吧。。这些奇葩的代码。。