【发布时间】:2010-01-07 00:00:03
【问题描述】:
我们有一个 winforms 应用程序每隔几秒就会调用一个存储过程。存储过程总是返回一个包含 0 行或更多行的结果集,并且客户端填充一个数据集。每隔几天左右,我们就会发现数据集中没有表,我们不知道为什么。触发存储过程的过程确实发生在一个线程中,但是数据库连接和存储过程的执行都发生在同一个线程中,因此这里没有任何数据在线程之间传递。
以前有没有人经历过这样的行为?
这里是相关代码,它是一个更大的应用程序的一部分,所以我尝试只包含相关位。
//Used by the main application to poll a database in a thread
public class Poller
{
private Thread thProcess_m;
private readonly Action<Exception> actOnError_m;
private readonly RuntimeData pRuntime_m;
private readonly DataAccessLayer dalDB_m;
private bool bRetry_m;
public Poller(RuntimeData pData, Action<Exception> actOnError)
{
this.thProcess_m = new Thread(Main);
this.thProcess_m.Name = "Main ScriptOr Polling Thread";
this.actOnError_m = actOnError;
this.dalDB_m = new DataAccessLayer(ConfigurationState.ConnectionStrings.DB);
}
public void Start()
{
this.thProcess_m.Start();
}
protected override void Main()
{
while (this.pRuntime_m.Running)
{
try
{
int iQueued;
Task pTask = this.dalDB_m.GetNextTask(out iQueued);
}
catch (Exception ex)
{
this.actOnError_m(ex);
}
}
}
}
public class RuntimeData
{
private bool bRunning_m;
public bool Running
{
get
{
return bRunning_m;
}
set
{
bRunning_m = value;
}
}
}
public class DataAcessLayer
{
public Task GetNextTask(out int iQueued)
{
iQueued = 0;
Task tskNext = null;
SqlCommand cmdNextTask = new SqlCommand();
cmdNextTask.CommandType = System.Data.CommandType.StoredProcedure;
cmdNextTask.CommandText = "pGetNextTask";
cmdNextTask.Connection = new System.Data.SqlClient.SqlConnection();
cmdNextTask.Connection.ConnectionString = "my connection string";
cmdNextTask.Connection.Open();
DataSet dsNextTask = new DataSet();
try
{
System.Data.SqlClient.SqlDataAdapter sqlNextTask = new System.Data.SqlClient.SqlDataAdapter(cmdNextTask);
sqlNextTask.Fill(dsNextTask);
}
finally
{
cmdNextTask.Connection.Close();
}
tskNext = LoadTask(dsNextTask);
if (dsTask.Tables[0].Rows.Count > 0)
{
iQueued = (int)dsTask.Tables[0].Rows[0]["Queued"];
}
return tskNext;
}
protected Task LoadTask(DataSet dsTask)
{
Task tskNext = null;
if (dsTask == null)
{
throw new ArgumentNullException("LoadTask DataSet is null.");
}
if (dsTask.Tables == null)
{
throw new NullReferenceException("LoadTask DataSet.Tables is null.");
}
//Here's where the exception is being thrown
if (dsTask.Tables.Count == 0)
{
throw new ArgumentOutOfRangeException("LoadTask DataSet.Tables.Count == 0.");
}
if (dsTask.Tables[0].Rows.Count > 0)
{
DataRow drTask = dsTask.Tables[0].Rows[0];
tskNext = new InteriorHealth.ScriptOr.ScriptTask((int)(drTask["id"]));
tskNext.Name = pRow["Name"].ToString();
}
return pTask;
}
}
【问题讨论】:
-
填充数据集的代码?