Ror*_*ory 5 .net debugging multithreading exception
我在错误日志中发现了这一点,并试图弄清楚这是怎么可能的。NullReferenceException 并不是每天都在 .net 基类的深处出现!
1) Exception Information
*********************************************
Exception Type: System.NullReferenceException
Message: Object reference not set to an instance of an object.
Data: System.Collections.ListDictionaryInternal
TargetSite: Void Bind(System.Data.SqlClient.TdsParserStateObject)
HelpLink: NULL
Source: System.Data
StackTrace Information
*********************************************
at System.Data.SqlClient.SqlDataReader.Bind(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 esult)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
at MyCode.Shared.Data.DataSocket.GetTable(String SPString)
at <rest of stack trace>
Run Code Online (Sandbox Code Playgroud)
我唯一能想到的是,有两个线程同时执行相同的方法,并且一个清除或修改了传递给 Fill() 的 DataSet 的可能性很小。所以我的问题是:
顺便说一句,我发现一对夫妇的这一问题的其他情况下,一个在此线程,另一个在这个别人的网页的谷歌缓存。两者似乎都没有任何帮助。
我正在执行的 GetTable() 方法如下所示:
public DataTable GetTable(string SPString)
{
//Setup the data objects by calling helper
prepareDataAdaptor(SPString,CommandType.Text);
dataAdaptor.Fill(dataSet);
dataAdaptor.SelectCommand.Connection.Close();
DataTable dt;
//ensure we dispose okay
using(dataSet)
{
if(dataSet.Tables.Count==0)
{
dataSet.Tables.Add(new DataTable("EmptyTable"));
}
dt=dataSet.Tables[0];
//because we are disposing we need to remove the table from the dataset
dataSet.Tables.Clear();
}
return dt;
}
private void prepareDataAdaptor(string SPString,CommandType Type)
{
checkForConnection();
dataSet=new DataSet();
dbCommand.CommandText=SPString;
dbCommand.CommandTimeout = MySettings.CommandTimeout;
dataAdaptor.SelectCommand=dbCommand;
dataAdaptor.SelectCommand.CommandType=Type;
dataAdaptor.SelectCommand.Connection=dbConnection;
dataAdaptor.SelectCommand.Parameters.Clear();
}
Run Code Online (Sandbox Code Playgroud)
dataAdaptor (sic) 是一个实例变量,声明为一个 IDbDataAdapter,填充了一个 SqlDataAdapter。dataSet 是 DataSet 类型的实例变量。
我的理论是线程 A 运行并进入 SqlDataAdapter.Fill() 方法。与此同时,线程 B 也在执行并做了一些让线程 A 混乱的事情,就像这一行:
dataAdaptor.SelectCommand.Connection.Close();
Run Code Online (Sandbox Code Playgroud)
我可以看到我的这段代码不是线程安全的,但是我如何确定这是导致上述异常的问题?
非常感谢您的任何建议!
罗里
编辑:修复了拼写错误的情况。没有在代码中更新它,因为它就是这样。
更新:我同意这段代码有几处错误应该修复,但我的主要兴趣是是否有任何方法可以验证是否是导致此错误的线程问题。鉴于我的应用程序,它有点牵强,但这是我唯一能想到的。在我修改代码以使其更好之前,我想确保我已经找到了异常的原因,以便我可以确定我已经修复了它。
例如,有没有办法进入 .net 代码?我正在使用 VS 2005 / .net 2.0 但我认为在 VS 2008 中您可以查看 .NET 框架源代码?如果是这种情况,我可以创建一个 2 线程场景并逐步解决这个问题吗?或者有没有不需要我安装 VS 2008 的方法?