C#线程读取和写入文件
我正在尝试这样做: 我有3个包含字符串的文件C#线程读取和写入文件,c#,multithreading,threadpool,readfile,writefile,C#,Multithreading,Threadpool,Readfile,Writefile,我正在尝试这样做: 我有3个包含字符串的文件 读取3个文件并创建包含3个文件内容的第4个文件 假设使用并行运行的线程进行读取 要为第四个文件写入的第四个线程 我的问题是,你如何正确阅读,如何确保第四个线程仅在所有文件都变红后运行,如何将字符串内容发送到第四个线程 阅读完这些文件后,第四个文件应该按照字典顺序包含字符串,删除任何空格、符号和重复的单词(不需要给出实现,只需建议在何处编写代码以及如何正确执行) 我使用了任务,我想知道如何使用线程 在这段代码中,字符串数组用于演示文件 如何正确读取每个
using System;
using System.Threading.Tasks;
using System.IO;
using System.Text;
class Program {
static void Main() {
StringBuilder stringToRead = new StringBuilder();
StringReader reader;
Task [] tasks = new Task[3];
string [] filz = {"aaa" , "bbb" , "ccc"};
string [] red = new string[filz.Length];
foreach(string str in filz){
stringToRead.AppendLine(str);
}
for (int i = 0; i < tasks.Length ; i++)
{
tasks[i] = Task.Run(() => Console.WriteLine(i)); // it prints 3 , 3 , 3
}
try {
Task.WaitAll(tasks);
}
catch (AggregateException ae) {
Console.WriteLine("One or more exceptions occurred: ");
foreach (var ex in ae.Flatten().InnerExceptions)
Console.WriteLine(" {0}", ex.Message);
}
Console.WriteLine("Status of completed tasks:");
foreach (var t in tasks)
Console.WriteLine(" Task #{0}: {1}", t.Id, t.Status);
//now:
//4th thread that will writh the 3 previous files that have been red and writh it to a new file
}
}
使用系统;
使用System.Threading.Tasks;
使用System.IO;
使用系统文本;
班级计划{
静态void Main(){
StringBuilder stringToRead=新建StringBuilder();
StringReader;
任务[]任务=新任务[3];
字符串[]filz={“aaa”、“bbb”、“ccc”};
字符串[]红色=新字符串[filz.Length];
foreach(filz中的字符串str){
stringToRead.AppendLine(str);
}
for(int i=0;iConsole.WriteLine(i));//它打印3,3,3
}
试一试{
Task.WaitAll(任务);
}
捕获(聚合异常ae){
WriteLine(“发生了一个或多个异常:”);
foreach(ae.flatte().InnerExceptions中的变量ex)
Console.WriteLine(“{0}”,例如Message);
}
Console.WriteLine(“已完成任务的状态:”);
foreach(任务中的var t)
WriteLine(“任务{0}:{1}”,t.Id,t.Status);
//现在:
//第四个线程,它将写入以前的3个红色文件,并将其写入新文件
}
}
以下是一个在.NET framework应用程序中使用wait的解决方案:
static void Main(string[] args)
{
try
{
var result = combineFiles().Result;
}
catch (ArgumentException aex)
{
Console.WriteLine($"Caught ArgumentException: {aex.Message}");
}
}
static async Task<bool> combineFiles()
{
List<Task> tasks = new List<Task>();
string path = "C:\\Temp\\testfileread\\";
Task<string> file1Read = ReadTextAsync(Path.Combine(path, "test1.txt"));
Task<string> file2Read = ReadTextAsync(Path.Combine(path, "test2.txt"));
Task<string> file3Read = ReadTextAsync(Path.Combine(path, "test3.txt"));
await Task.WhenAll(file1Read, file2Read, file3Read);
string text1 = await file1Read;
string text2 = await file2Read;
string text3 = await file3Read;
await WriteTextAsync(Path.Combine(path, "result.txt"), text1 + text2 + text3);
Console.WriteLine("Finished combining files");
Console.ReadLine();
return true;
}
private static async Task<string> ReadTextAsync(string filePath)
{
using (var reader = File.OpenText(filePath))
{
var fileText = await reader.ReadToEndAsync();
return fileText;
}
}
private static async Task WriteTextAsync(string filePath, string value)
{
using (StreamWriter writer = File.CreateText(filePath))
{
await writer.WriteAsync(value);
}
}
这是一个按钮单击事件,请注意函数定义中的“async”:
private async void button1_Click(object sender, EventArgs e)
{
List<Task> tasks = new List<Task>();
string path = "C:\\Temp\\testfileread\\";
Task<string> file1Read = ReadTextAsync(Path.Combine(path, "test1.txt"));
Task<string> file2Read = ReadTextAsync(Path.Combine(path, "test2.txt"));
Task<string> file3Read = ReadTextAsync(Path.Combine(path, "test3.txt"));
await Task.WhenAll(file1Read, file2Read, file3Read);
string text1 = await file1Read;
string text2 = await file2Read;
string text3 = await file3Read;
await WriteTextAsync(Path.Combine(path, "result.txt"), text1 + text2 + text3);
}
您需要如何重新组装新文件?新文件是否必须按特定顺序生成?如果您读取的每个文件都有不同的大小,则读取它们所需的时间将不同。。。您是否需要按顺序重新组装文件,或者顺序可能与读取顺序不同?如果顺序必须保持不变,则您需要等待所有读取线程,然后启动写入进程。我认为文件的顺序无关紧要,只是在我写入新文件之前确保每个文件都是红色的仅供参考,对于路径聚合,最好使用path.Combine而不是
path+'file.txt'
感谢您建议使用async/await!在并发异步任务代码可以正常工作的情况下,没有理由使用线程。由于OP使用的是控制台应用程序,值得一提的是,C#/.NET的最新版本允许使用async
Main方法。@StriplingWarrior没有理由使用线程是什么意思,他正在使用任务,这不是考虑过的线程吗,我还提到了线程也可以这样做,你知道如何做到高效吗,另外,祖卢卡斯,你能给出一个在这种情况下路径合并的代码示例吗?@CarCar你能解释为什么第一个函数叫做button click,为什么它有未使用的对象发送器吗?例如,如何将此解决方案与main结合?修改答案以使用Path.combine
static void Main(string[] args)
{
try
{
var result = combineFiles().Result;
}
catch (ArgumentException aex)
{
Console.WriteLine($"Caught ArgumentException: {aex.Message}");
}
}
static async Task<bool> combineFiles()
{
List<Task> tasks = new List<Task>();
string path = "C:\\Temp\\testfileread\\";
Task<string> file1Read = ReadTextAsync(Path.Combine(path, "test1.txt"));
Task<string> file2Read = ReadTextAsync(Path.Combine(path, "test2.txt"));
Task<string> file3Read = ReadTextAsync(Path.Combine(path, "test3.txt"));
await Task.WhenAll(file1Read, file2Read, file3Read);
string text1 = await file1Read;
string text2 = await file2Read;
string text3 = await file3Read;
await WriteTextAsync(Path.Combine(path, "result.txt"), text1 + text2 + text3);
Console.WriteLine("Finished combining files");
Console.ReadLine();
return true;
}
private static async Task<string> ReadTextAsync(string filePath)
{
using (var reader = File.OpenText(filePath))
{
var fileText = await reader.ReadToEndAsync();
return fileText;
}
}
private static async Task WriteTextAsync(string filePath, string value)
{
using (StreamWriter writer = File.CreateText(filePath))
{
await writer.WriteAsync(value);
}
}
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;