Tal
Tal

Reputation: 29

C# Threads read and write files

I am trying to do something like this:

I have 3 files which contain strings

  1. read 3 files and create a 4th file which contains the 3 files content
  2. the reading is suppose to be done with threads which will run in parallel
  3. 4th thread to write for the 4th file

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

Answers (1)

CarCar
CarCar

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

Related Questions