Reputation: 29
I am trying to do something like this:
I have 3 files which contain strings
my questions are , how do you do the reading properly ? , how do you make sure that the 4th thread will only run after all files have been red, how do you get the strings content to the 4th thread ?
after reading the files , the 4th files should contain the strings in lexicography order, delate any spaces , signs and repeated words (no need to give implementation of that, just recommend where to code this and how to do it properly)
I used tasks , I want to know how to use threads as well for that in this code the strings array is to demonstrate the files
how do i properly read the file in the "run" function of each thread?
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
}
}
Upvotes: 2
Views: 2588
Reputation: 680
Here is a solution using await in a .NET framework application:
This is a button click event, notice the "async" in the function definition:
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);
}
Here are the read and write functions:
private async Task<string> ReadTextAsync(string filePath)
{
using (var reader = File.OpenText(filePath))
{
var fileText = await reader.ReadToEndAsync();
return fileText;
}
}
private async Task WriteTextAsync(string filePath, string value)
{
using (StreamWriter writer = File.CreateText(filePath))
{
await writer.WriteAsync(value);
}
}
The code is nearly the same but here is a solution done in a .NET Core console Application:
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);
}
}
dont forget the needed using lines:
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
Upvotes: 2