以前老帖的地址:http://topic.csdn.net/u/20111118/14/5482094d-43aa-4031-a76b-f946daa63047.html?1297994050
问题重复一遍吧
/// <summary>
/// 获取数据源
/// </summary>
/// <returns></returns>
private SqlDataReader GetSource()
{
SqlConnection con = new SqlConnection("server=.;database=TestDB;uid=sa;pwd=123");
con.Open();
SqlCommand cmd = new SqlCommand(string.Format("select {0} from Testtbl", txtShowStr.Text), con);
return cmd.ExecuteReader();
}
private void CreateIndex()
{
SqlDataReader myred = GetSource();
try
{
while (myred.Read())
{
WriteFile("path",myred["Content"].ToString());
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); } }
private void btnAddIdx_Click(object sender, EventArgs e)
{
//CreateIndex(); //不使用线程不抱错
Thread thread = new Thread(new ThreadStart(CreateIndex));
thread.IsBackground = true;
thread.Start(); //使用线程报错
//WriteFile其实就是使用File.AppendAllText;当然myred["Content"]是作了一下字符串替换和组合,不是一个字段,而是读出来的数据字段。报错:
debug报错是停在Application.Run(new MainFrm());这句。
错误信息:
索引超出范围。必须为非负值并小于集合大小。
参数名: index
个人认为:不是出现在写文件中,原因是写文件只是一个线程在操作。而是在数据遍历的地方。
测试程序时,在不使用线程的时候是可以通过的,当使用线程的时候。一般在遍历到8W-16W左右报错。我的猜想:
是不是资源被提前释放了。对于出错的具体地方我无法找到。各位大大是否有什么办法能够找到具体出错的地方。麻烦告知,谢谢!还有就是什么使用委托的就不要说了吧,我就是想知道为什么会出现这种情况。
再次谢谢各位!
问题重复一遍吧
/// <summary>
/// 获取数据源
/// </summary>
/// <returns></returns>
private SqlDataReader GetSource()
{
SqlConnection con = new SqlConnection("server=.;database=TestDB;uid=sa;pwd=123");
con.Open();
SqlCommand cmd = new SqlCommand(string.Format("select {0} from Testtbl", txtShowStr.Text), con);
return cmd.ExecuteReader();
}
private void CreateIndex()
{
SqlDataReader myred = GetSource();
try
{
while (myred.Read())
{
WriteFile("path",myred["Content"].ToString());
}
}
catch (Exception ex) { MessageBox.Show(ex.Message); } }
private void btnAddIdx_Click(object sender, EventArgs e)
{
//CreateIndex(); //不使用线程不抱错
Thread thread = new Thread(new ThreadStart(CreateIndex));
thread.IsBackground = true;
thread.Start(); //使用线程报错
//WriteFile其实就是使用File.AppendAllText;当然myred["Content"]是作了一下字符串替换和组合,不是一个字段,而是读出来的数据字段。报错:
debug报错是停在Application.Run(new MainFrm());这句。
错误信息:
索引超出范围。必须为非负值并小于集合大小。
参数名: index
个人认为:不是出现在写文件中,原因是写文件只是一个线程在操作。而是在数据遍历的地方。
测试程序时,在不使用线程的时候是可以通过的,当使用线程的时候。一般在遍历到8W-16W左右报错。我的猜想:
是不是资源被提前释放了。对于出错的具体地方我无法找到。各位大大是否有什么办法能够找到具体出错的地方。麻烦告知,谢谢!还有就是什么使用委托的就不要说了吧,我就是想知道为什么会出现这种情况。
再次谢谢各位!
WriteFile("path","xxx");
看这样还出问题吗?
如果不出问题了,那么是你取数据的问题,如果还出问题,是你写文件的问题。
比如
//线程类
public Class MyThreadClass
{
string[] arrayStr;
public MyThreadClass(string[] arrayStr)
{
this.arrayStr = arrayStr;
}//线程主方法
public void Work()
{
//处理数组
foreach(string str in arrayStr)
{
// do something
...
}}
}//调用线程类
string[] myArray;
MyThreadClass myThread = new MyThreadClass(myArray);
new Thread(new ThreadStart(myThread.Work)).Start();
/// 获取数据源
/// </summary>
/// <returns></returns>
private SqlDataReader GetSource()
{
SqlConnection con = new SqlConnection("server=.;database=TestDB;uid=sa;pwd=123");
con.Open();
SqlCommand cmd = new SqlCommand(string.Format("select {0} from Testtbl", txtIdxStr.Text), con);
return cmd.ExecuteReader();
}
private void Test()
{
int count = 0;
myred = GetSource();
try
{
while (myred.Read())
{
tsslResult.Text = string.Format("当前遍历数据{0}条", ++count);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
调试结果,仍然报相同的错误。
死锁??
不懂。
Thread thread = new Thread(new ThreadStart(CreateIndex));
thread.IsBackground = true;
thread.Start(); //使用线程报错
改成: private void btnAddIdx_Click(object sender, EventArgs e)
{
CheckForIllegalCrossThreadCalls = false;
//CreateIndex(); //不使用线程不抱错
Thread thread = null;
ThreadStart start=new ThreadStart();
thread=new ThreadStart(CreateIndex);
//thread.IsBackground = true;
thread.Start(); CheckForIllegalCrossThreadCalls = false;
根据你提供的错误信息不是在线程中爆的错
而且你提供的代码貌似不会出现这个情况我估计有可能你的数据源为空
或者在引用 datatable的时候 索引超出范围 datatable索引是从0开始的当你数据源为空会出现这个情况 还有就是索引 也就是index的只大于datatable.Rows.Count的时候
是你数据读取那块需要加个锁的问题产生原因: 当你另外开一个线程走你那个查询数据的方法的时候 同时你原来的主线程中也有一些与库进行交互的方法 同时 这些方法调用的都是同一个Connection对象 ,必然会出问题。解决方案如下:
private object padlock = new object(); private SqlDataReader GetSource()
{
lock (padlock)
{ SqlConnection con = new SqlConnection("server=.;database=TestDB;uid=sa;pwd=123");
con.Open();
SqlCommand cmd = new SqlCommand(string.Format("select {0} from Testtbl", txtIdxStr.Text), con);
return cmd.ExecuteReader();
}
}
private void Test()
{
int count = 0;
myred = GetSource();
try
{
while (myred.Read())
{
tsslResult.Text = string.Format("当前遍历数据{0}条", ++count);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
还有就是所有与库操作的东西 都加上这个锁的机制。当然了 这样的性能要受到影响 lz可以根据实际情况 进行锁控制。 最好是对锁控制进行优化