C# 如何使用foreach循环制作多线程应用程序
有一个应用程序排序大txt文件的一些条件。 例如,我需要启动5个线程,但我使用foreach循环逐行读取文件。 如果我用我的代码启动5个线程,那么所有线程都将使用相同的行 这是我的代码,我从这里开始1个线程:C# 如何使用foreach循环制作多线程应用程序,c#,multithreading,C#,Multithreading,有一个应用程序排序大txt文件的一些条件。 例如,我需要启动5个线程,但我使用foreach循环逐行读取文件。 如果我用我的代码启动5个线程,那么所有线程都将使用相同的行 这是我的代码,我从这里开始1个线程: Thread[] thr; private void button1_Click(object sender, EventArgs e) { button1.Enabled = false; button4.Enabled = tru
Thread[] thr;
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
button4.Enabled = true;
decimal value = 1;
int i = 0;
int j = (int)(value);
thr = new Thread[j];
for (; i < j; i++)
{
thr[i] = new Thread(new ThreadStart(go));
thr[i].IsBackground = true;
thr[i].Start();
}
}
private static IEnumerable<string> ReadLineFromFile(TextReader fileReader)
{
using (fileReader)
{
string currentLine;
while ((currentLine = fileReader.ReadLine()) != null)
{
yield return currentLine;
}
}
}
public void go()
{
while (true)
{
TextReader readFile = new StreamReader(file_path, System.Text.Encoding.UTF8, true);
foreach (string line in ReadLineFromFile(readFile))
{
if (line.Split(':')[0].Contains("@"))
{
string out_line = line.Split(':')[0].Replace("+", "") + ":" + line.Split(':')[1];
lock (locker)
{
mail_count++;
log_mail(mail_count);
mail.Add(out_line.Trim().Replace(";", ":"));
}
}
else
{
string out_line = line.Split(':')[0].Replace("+", "") + ":" + line.Split(':')[1];
lock (locker)
{
rubbish_count++;
log_rubbish(rubbish_count);
rubbish.Add(out_line.Trim());
}
}
}
MessageBox.Show("Ready");
BeginInvoke(
new MethodInvoker(() =>
{
button1.Enabled = true;
button4.Enabled = false;
}));
break;
}
}
Thread[]thr;
私有无效按钮1\u单击(对象发送者,事件参数e)
{
按钮1.启用=错误;
按钮4.Enabled=true;
十进制值=1;
int i=0;
int j=(int)(值);
thr=新螺纹[j];
对于(;i
{
按钮1.启用=真;
按钮4.Enabled=false;
}));
打破
}
}
为什么不采用通常的生产者-消费者模式?让一个线程读取文件,将行放在某个共享集合中,而其他线程只是从集合中拾取数据并对其进行处理
更多-您可以从文件中读取并为每一行创建任务
,该任务将负责处理此行并将结果放入输出集合
这似乎比5个线程尝试读取同一个文件而不多次读取同一行要好。为什么不使用通常的生产者-消费者模式?让一个线程读取文件,将行放在某个共享集合中,而其他线程只是从集合中拾取数据并对其进行处理 更多-您可以从文件中读取并为每一行创建
任务
,该任务将负责处理此行并将结果放入输出集合
这似乎比5个线程尝试读取同一文件而不多次读取同一行要好。所有线程都读取同一文件是没有用的,从共享文件读取是困难和低效的 在您的主要功能中,您需要以下内容:
Parallel.ForEach(System.IO.File.ReadLines(file_path, System.Text.Encoding.UTF8),
line => ProcessOneLine(line)
);
然后ProcessOneLine将执行
.Split(“:”)
等操作。所有线程读取同一个文件是没有用的,从共享文件读取是困难和低效的
在您的主要功能中,您需要以下内容:
Parallel.ForEach(System.IO.File.ReadLines(file_path, System.Text.Encoding.UTF8),
line => ProcessOneLine(line)
);
然后ProcessOneLine将执行
.Split(“:”)
等操作。我想确认一下Pako所说的内容,并进一步说明。其他线程应该使用包含数据的共享集合中的数据并对其进行处理
让多个线程访问一个文本文件听起来很有可能出现争用情况。如果一个线程正在更改一个文件,而另一个线程正在读取该文件,则可能会出现本质上不可预测的结果
在过去,当使用多个线程访问同一个文本文件时,我也遇到过BSODs,并且可以建议不要使用它。但是,如果您坚持这样做,我建议您查看一下“lock”关键字和singleton设计模式。这将允许您确保一次只有一个线程访问该文件
相关链接:
我想确认并详述Pako所说的话。其他线程应该使用包含数据的共享集合中的数据并对其进行处理 让多个线程访问一个文本文件听起来很有可能出现争用情况。如果一个线程正在更改一个文件,而另一个线程正在读取该文件,则可能会出现本质上不可预测的结果 在过去,当使用多个线程访问同一个文本文件时,我也遇到过BSODs,并且可以建议不要使用它。但是,如果您坚持这样做,我建议您查看一下“lock”关键字和singleton设计模式。这将允许您确保一次只有一个线程访问该文件 相关链接:
老实说,无论您做什么,您的硬盘在给定的时间内只能处于一个位置,因此“并行”文件读取没有实际意义。但是,您可以为开始读取文件的每个线程提供一个偏移量,但这不会加快任何速度^^^^如果您真的想加快功能,则必须使用磁盘缓存,这对您有利:在实际需要文件之前开始读取文件。这将自动将文件加载到内存(),然后您可以在实际需要时从RAM中读取它。然后您可以充分利用Pako生产者-消费者模式。老实说,无论您做什么,您的硬盘都可以