以前老帖的地址: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左右报错。我的猜想:
是不是资源被提前释放了。对于出错的具体地方我无法找到。各位大大是否有什么办法能够找到具体出错的地方。麻烦告知,谢谢!还有就是什么使用委托的就不要说了吧,我就是想知道为什么会出现这种情况。
再次谢谢各位!

解决方案 »

  1.   

    调试这句:WriteFile("path",myred["Content"].ToString()); 
    WriteFile("path","xxx"); 
    看这样还出问题吗?
    如果不出问题了,那么是你取数据的问题,如果还出问题,是你写文件的问题。
      

  2.   

    在使用线程的时候,有些参数是需要传入你的线程的。
    比如
    //线程类
    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();
      

  3.   

    调试代码: /// <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", 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);
                }
            }
    调试结果,仍然报相同的错误。
      

  4.   

    invoke??
    死锁??
    不懂。
      

  5.   

    还有我使用的try...catch  如果是myred.Read()这里出错,错误信息不是应该被捕捉到了吗?但是错误信息仍然出现在Main()函数中。无法理解。经过精简我现在就只是用到了这2个给出的函数。
      

  6.   


    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;
      

  7.   

    sorry 没有看见
    根据你提供的错误信息不是在线程中爆的错
    而且你提供的代码貌似不会出现这个情况我估计有可能你的数据源为空
    或者在引用 datatable的时候 索引超出范围 datatable索引是从0开始的当你数据源为空会出现这个情况 还有就是索引 也就是index的只大于datatable.Rows.Count的时候
      

  8.   

    哈哈 lz  这个问题是这样的……
    是你数据读取那块需要加个锁的问题产生原因: 当你另外开一个线程走你那个查询数据的方法的时候  同时你原来的主线程中也有一些与库进行交互的方法  同时 这些方法调用的都是同一个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可以根据实际情况 进行锁控制。  最好是对锁控制进行优化
      

  9.   

    sorry,我重开一个项目,并将代码拷贝进去,发现不报错了!让我检查检查,有什么地方不一样!一会给出结果,谢谢各位!