写一个多线程处理文件的程序,按照“代码块1”的方法调用多线程模块对单一文件进行处理,程序运行正常,结果也正确。
但当要对一组文件进行处理时(代码为“代码块2”),程序异常退出,无法往下执行,想想应该是线程冲突造成的。
本人新近才接触多线程编程,不知如何写代码(button1_Click),才能将文件列表 filelist 中的文件依次正确处理。
namespace test
{
    public class Form1 : System.Windows.Forms.Form
    {
        ...
        private void button1_Click(object sender, System.EventArgs e) {            string[] filelist = new string[2];
            filelist[0] = @"C:\test1.txt";
            filelist[1] = @"C:\test2.txt";            //代码块1
            ParseFile pfile = new ParseFile(filelist[0].ToString());
            /*
            //代码块2
            ParseFile pfile;
            for(int i=0;i<2;i++)
            {
                pfile = new ParseFile(filelist[i].ToString());
            }
            */
        }
    }
    class ParseFile
    {
        public ParseFile(string filename)
        {
            this._filename = filename;
            //创建线程
            for(int i =0;i < 2;i++ )
            {
                Thread thread = new Thread(new ThreadStart(ThreadParse));
                thread.Name = "Thread"+i.ToString();
                thread.Start();
            }
        }
        public void ThreadParse()
        {
            FileStream fs = new FileStream(_filename,FileMode.Open,FileAccess.Read);
            ...
        }
    }
}

解决方案 »

  1.   

    每次输出的时候让线程sleep一下了
      

  2.   

    我也在编线程与你出现差不多同样的问题,建议你看看“委托”,这个我理解是线程的高级编程。
    代码方式如下:1、委托程序
           private void WriteLog(string content)
            {
    //内容自己写
    }2、委托手柄delegate void WriteLogHandle(string content);
    3、委托使用方法this.Invoke(new WriteLogHandle(WriteLog),new object[]{"委托参数"});
      

  3.   

    支持3楼,但个人认为用beginInvoke比较好~
      

  4.   

    你的意思是将写操作从ThreadParse()中独立出来定义为委托程序,在需要写操作时,在ThreadParse()中调委托程序?
    说实在,委托这块我还得加强。
      

  5.   

    错误,是把ThreadParse()写成一个普通的方法,然后用委托调用
      

  6.   

    ThreadParse()中独立出来定义为委托程序
    -----------------
    对,相当于委托程序
      

  7.   

    public ParseFile(string filename)
    {
      this._filename = filename;
      //创建线程
      Thread thread = new Thread(new ThreadStart(ThreadParse));
      thread.Name = "Thread"+filename;
      thread.Start();
    }
      

  8.   

    感觉用后台线程backgroundWorker比较合适
    backgroundWorker有IsBusy属性,可以判断线程是否处于忙碌状态。
      

  9.   

      //代码块2
      ParseFile pfile;
      for(int i=0;i<2;i++)
      {
      pfile = new ParseFile(filelist[i].ToString()); //错在这里了
      }
    原因:
    第一次遍历后
    pfile 被创建执行
    第二次遍历时 pfile 将要被销毁重新创建,问题是 pfile 里的线程可能还没有执行完毕,所以 pfile 在重新赋值是出现异常。可以把
    ParseFile pfile;
    声明成数组形式如:
    ParseFile[] pfile;
    那么遍历时:
     for(int i=0;i<2;i++)
      {
      pfile[i] = new ParseFile(filelist[i].ToString()); //错在这里了
      }
      

  10.   

    按10楼的方法,代码执行没有结果。8楼的方法,我已经在用,不过是包含在for()循环中,实现多线程处理。
      

  11.   

    Thread thread = new Thread(new ThreadStart(ThreadParse));
      thread.Name = "Thread"+i.ToString();
      thread.Start();是 监视 线程,起的中断左右。  如果 执行代码块一般都是用异步线程。异步线程 很简单,1个函数,一个委托,然后定义 一下,还能 传参数。
    当异步线程执行的时候, 系统会分配出1段线程 执行你的代码模块。你线程下面的其他程序  还可以继续执行 你用的线程 是监视用的,比如 适时捕获网络来的数据。等作用。
      

  12.   

    刚接触的多线程,还有委托,不太理解,能不能贴点简单代码?THX
      

  13.   

    3楼说的正确 
    //这个是你 要执行的程序段函数 ,比如 这个函数 ,你想 读取 数据库的 很多内容 。你写在这个函数里。
      private void WriteLog(string content)
      {
    //内容自己写
    }
    //然后定义1个委托 ,参数必须 和 你 执行的函数  delegate void WriteLogHandle(string content);
    然后 用委托 定义1个WriteLogHandle handler = new WriteLogHandle(WriteLog); //参数里填 你要执行的程序段的函数。handler.BeginInvoke( "这里填参数",null,null,null); //这时候 就单独 分配一段 线程去执行你的模块了。然后程序段继续往下执行。不影响你主程序执行。
    如果需要两个参数就 
    handler.BeginInvoke( "这里填参数","第2个"null,null);如果报参数不正确就多填几个 null直到够了为止,大概是这样的。你试试吧
      

  14.   

    //读取数据库内容 
    private void readdataList(string name)
    {
       //读取数据库。
    }//定义的委托 返回值,参数 必须 与 dataList一样 
    delegate void readdataListgHandle(string name);
    比如  你想在按钮里执行 1.先 改变 文本框,2.读取数据库内容 3.再次改变文本框内容this.textbox.Text = "滚";//2.用线程读取 数据库
    readdataListgHandle handler = new readdataListgHandle(readdataList); //指定要用线程执行的函数
    handler.BeginInvoke( "这里填参数",null,null,null); //这句话执行完了 ,系统分配一段线程执行 readdataList函数 内的内容。分配完毕。继续执行 下面的代码this.textbox.Text = "给我滚!!!";