写一个多线程处理文件的程序,按照“代码块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);
...
}
}
}
但当要对一组文件进行处理时(代码为“代码块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、委托程序
private void WriteLog(string content)
{
//内容自己写
}2、委托手柄delegate void WriteLogHandle(string content);
3、委托使用方法this.Invoke(new WriteLogHandle(WriteLog),new object[]{"委托参数"});
说实在,委托这块我还得加强。
-----------------
对,相当于委托程序
{
this._filename = filename;
//创建线程
Thread thread = new Thread(new ThreadStart(ThreadParse));
thread.Name = "Thread"+filename;
thread.Start();
}
backgroundWorker有IsBusy属性,可以判断线程是否处于忙碌状态。
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()); //错在这里了
}
thread.Name = "Thread"+i.ToString();
thread.Start();是 监视 线程,起的中断左右。 如果 执行代码块一般都是用异步线程。异步线程 很简单,1个函数,一个委托,然后定义 一下,还能 传参数。
当异步线程执行的时候, 系统会分配出1段线程 执行你的代码模块。你线程下面的其他程序 还可以继续执行 你用的线程 是监视用的,比如 适时捕获网络来的数据。等作用。
//这个是你 要执行的程序段函数 ,比如 这个函数 ,你想 读取 数据库的 很多内容 。你写在这个函数里。
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直到够了为止,大概是这样的。你试试吧
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 = "给我滚!!!";